From fac7dbb15dd6717a18d9361533ad8d6cca8ce7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ukasik?= Date: Wed, 20 Feb 2019 19:39:48 +0100 Subject: Add keywords to desktop file Gbp-Pq: Name add-keywords.patch --- audacious.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/audacious.desktop b/audacious.desktop index fe29e70..9061f13 100644 --- a/audacious.desktop +++ b/audacious.desktop @@ -5,6 +5,7 @@ Name=Audacious GenericName=Music Player Comment=Listen to music Icon=audacious +Keywords=audio;player;audacious;music;gtk; Categories=AudioVideo;Audio;Player;GTK; Exec=audacious %U TryExec=audacious -- cgit v1.2.3 From d42f034234121a823254fd656e21338fe8ef8cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ukasik?= Date: Sun, 22 Mar 2020 22:19:48 +0100 Subject: Add keywords to desktop file Gbp-Pq: Name add-keywords.patch --- audacious.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/audacious.desktop b/audacious.desktop index 1ecd8c9..0265347 100644 --- a/audacious.desktop +++ b/audacious.desktop @@ -5,6 +5,7 @@ Name=Audacious GenericName=Music Player Comment=Listen to music Icon=audacious +Keywords=audio;player;audacious;music;gtk; Categories=AudioVideo;Audio;Player;GTK; Exec=audacious %U TryExec=audacious -- cgit v1.2.3 From 2749880410fdaa370cfc0853e663cd674784e7ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ukasik?= Date: Sun, 22 Mar 2020 23:49:12 +0100 Subject: Add keywords to desktop file Gbp-Pq: Name add-keywords.patch --- audacious.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/audacious.desktop b/audacious.desktop index 1ecd8c9..0265347 100644 --- a/audacious.desktop +++ b/audacious.desktop @@ -5,6 +5,7 @@ Name=Audacious GenericName=Music Player Comment=Listen to music Icon=audacious +Keywords=audio;player;audacious;music;gtk; Categories=AudioVideo;Audio;Player;GTK; Exec=audacious %U TryExec=audacious -- cgit v1.2.3 From 9b7a684e30c56649464e424e9a603c8988f54620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ukasik?= Date: Mon, 23 Mar 2020 13:26:49 +0100 Subject: Add keywords to desktop file Gbp-Pq: Name add-keywords.patch --- audacious.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/audacious.desktop b/audacious.desktop index 1ecd8c9..0265347 100644 --- a/audacious.desktop +++ b/audacious.desktop @@ -5,6 +5,7 @@ Name=Audacious GenericName=Music Player Comment=Listen to music Icon=audacious +Keywords=audio;player;audacious;music;gtk; Categories=AudioVideo;Audio;Player;GTK; Exec=audacious %U TryExec=audacious -- cgit v1.2.3 From 269b9ab446b2b2eca80f48bc104dc536629c01c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ukasik?= Date: Sat, 18 Apr 2020 12:52:42 +0200 Subject: Add keywords to desktop file Gbp-Pq: Name add-keywords.patch --- audacious.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/audacious.desktop b/audacious.desktop index 1ecd8c9..0265347 100644 --- a/audacious.desktop +++ b/audacious.desktop @@ -5,6 +5,7 @@ Name=Audacious GenericName=Music Player Comment=Listen to music Icon=audacious +Keywords=audio;player;audacious;music;gtk; Categories=AudioVideo;Audio;Player;GTK; Exec=audacious %U TryExec=audacious -- cgit v1.2.3 From 5489c14f874980cbdddd32bb0efa447dcba3550e Mon Sep 17 00:00:00 2001 From: Andrej Shadura Date: Sat, 18 Apr 2020 12:52:42 +0200 Subject: Default to the GTK interface, not Qt Gbp-Pq: Name default-to-gtk.patch --- src/audacious/main.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/audacious/main.cc b/src/audacious/main.cc index 1213a95..3c56676 100644 --- a/src/audacious/main.cc +++ b/src/audacious/main.cc @@ -50,6 +50,7 @@ static struct { int mainwin, show_jump_box; int headless, quit_after_play; int verbose; + int qt; int gtk; } options; @@ -78,6 +79,7 @@ static const struct { {"quit-after-play", 'q', & options.quit_after_play, N_("Quit on playback stop")}, {"verbose", 'V', & options.verbose, N_("Print debugging messages (may be used twice)")}, #if defined(USE_QT) && defined(USE_GTK) + {"qt", 'Q', & options.qt, N_("Run in Qt mode")}, {"gtk", 'G', & options.gtk, N_("Run in GTK mode")}, #endif }; @@ -171,8 +173,16 @@ static bool parse_options (int argc, char * * argv) else if (options.verbose) audlog::set_stderr_level (audlog::Info); - if (options.gtk) + if (options.qt && options.gtk) { + fprintf (stderr, _("Conflicting options: --gtk and --qt\n")); + return false; + } + + if (options.qt) { + aud_set_mainloop_type (MainloopType::Qt); + } else { aud_set_mainloop_type (MainloopType::GLib); + } return true; } -- cgit v1.2.3 From 18c6f31ba84570715c16bf4e19507555e37a28a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ukasik?= Date: Sun, 19 Apr 2020 12:03:44 +0200 Subject: Add keywords to desktop file Gbp-Pq: Name add-keywords.patch --- audacious.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/audacious.desktop b/audacious.desktop index 799a50f..9384087 100644 --- a/audacious.desktop +++ b/audacious.desktop @@ -5,6 +5,7 @@ Name=Audacious GenericName=Music Player Comment=Listen to music Icon=audacious +Keywords=audio;player;audacious;music;gtk; Categories=AudioVideo;Audio;Player;GTK; Exec=audacious %U TryExec=audacious -- cgit v1.2.3 From 356442525d8bd0f134c273695e9bfd2a45cdf528 Mon Sep 17 00:00:00 2001 From: Andrej Shadura Date: Sun, 19 Apr 2020 12:03:44 +0200 Subject: Default to the GTK interface, not Qt Gbp-Pq: Name default-to-gtk.patch --- src/audacious/main.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/audacious/main.cc b/src/audacious/main.cc index 1213a95..3c56676 100644 --- a/src/audacious/main.cc +++ b/src/audacious/main.cc @@ -50,6 +50,7 @@ static struct { int mainwin, show_jump_box; int headless, quit_after_play; int verbose; + int qt; int gtk; } options; @@ -78,6 +79,7 @@ static const struct { {"quit-after-play", 'q', & options.quit_after_play, N_("Quit on playback stop")}, {"verbose", 'V', & options.verbose, N_("Print debugging messages (may be used twice)")}, #if defined(USE_QT) && defined(USE_GTK) + {"qt", 'Q', & options.qt, N_("Run in Qt mode")}, {"gtk", 'G', & options.gtk, N_("Run in GTK mode")}, #endif }; @@ -171,8 +173,16 @@ static bool parse_options (int argc, char * * argv) else if (options.verbose) audlog::set_stderr_level (audlog::Info); - if (options.gtk) + if (options.qt && options.gtk) { + fprintf (stderr, _("Conflicting options: --gtk and --qt\n")); + return false; + } + + if (options.qt) { + aud_set_mainloop_type (MainloopType::Qt); + } else { aud_set_mainloop_type (MainloopType::GLib); + } return true; } -- cgit v1.2.3 From 305e6452b0ae2503953c328cc413d8a3b6adcb96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ukasik?= Date: Wed, 3 Jun 2020 15:53:26 +0200 Subject: Add keywords to desktop file Gbp-Pq: Name add-keywords.patch --- audacious.desktop | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/audacious.desktop b/audacious.desktop index 804b27c..a0827e6 100644 --- a/audacious.desktop +++ b/audacious.desktop @@ -5,7 +5,8 @@ Name=Audacious GenericName=Music Player Comment=Listen to music Icon=audacious -Categories=AudioVideo;Audio;Player; +Keywords=audio;player;audacious;music;gtk; +Categories=AudioVideo;Audio;Player;GTK; Exec=audacious %U TryExec=audacious StartupNotify=false -- cgit v1.2.3 From 65ba4cf7841e8ec0bdcb57f5c395544103a1323a Mon Sep 17 00:00:00 2001 From: Andrej Shadura Date: Wed, 3 Jun 2020 15:53:26 +0200 Subject: Default to the GTK interface, not Qt Gbp-Pq: Name default-to-gtk.patch --- src/audacious/main.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/audacious/main.cc b/src/audacious/main.cc index 1213a95..3c56676 100644 --- a/src/audacious/main.cc +++ b/src/audacious/main.cc @@ -50,6 +50,7 @@ static struct { int mainwin, show_jump_box; int headless, quit_after_play; int verbose; + int qt; int gtk; } options; @@ -78,6 +79,7 @@ static const struct { {"quit-after-play", 'q', & options.quit_after_play, N_("Quit on playback stop")}, {"verbose", 'V', & options.verbose, N_("Print debugging messages (may be used twice)")}, #if defined(USE_QT) && defined(USE_GTK) + {"qt", 'Q', & options.qt, N_("Run in Qt mode")}, {"gtk", 'G', & options.gtk, N_("Run in GTK mode")}, #endif }; @@ -171,8 +173,16 @@ static bool parse_options (int argc, char * * argv) else if (options.verbose) audlog::set_stderr_level (audlog::Info); - if (options.gtk) + if (options.qt && options.gtk) { + fprintf (stderr, _("Conflicting options: --gtk and --qt\n")); + return false; + } + + if (options.qt) { + aud_set_mainloop_type (MainloopType::Qt); + } else { aud_set_mainloop_type (MainloopType::GLib); + } return true; } -- cgit v1.2.3 From db3ea04f8e5f416ba18983914fada93d5be4a01f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ukasik?= Date: Wed, 6 Jan 2021 16:07:19 +0100 Subject: Add keywords to desktop file Gbp-Pq: Name add-keywords.patch --- audacious.desktop | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/audacious.desktop b/audacious.desktop index 804b27c..a0827e6 100644 --- a/audacious.desktop +++ b/audacious.desktop @@ -5,7 +5,8 @@ Name=Audacious GenericName=Music Player Comment=Listen to music Icon=audacious -Categories=AudioVideo;Audio;Player; +Keywords=audio;player;audacious;music;gtk; +Categories=AudioVideo;Audio;Player;GTK; Exec=audacious %U TryExec=audacious StartupNotify=false -- cgit v1.2.3 From b1580ead91ab77244312980d1c0eb37ba544fc34 Mon Sep 17 00:00:00 2001 From: Andrej Shadura Date: Wed, 6 Jan 2021 16:07:19 +0100 Subject: Default to the GTK interface, not Qt Gbp-Pq: Name default-to-gtk.patch --- src/audacious/main.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/audacious/main.cc b/src/audacious/main.cc index 1213a95..3c56676 100644 --- a/src/audacious/main.cc +++ b/src/audacious/main.cc @@ -50,6 +50,7 @@ static struct { int mainwin, show_jump_box; int headless, quit_after_play; int verbose; + int qt; int gtk; } options; @@ -78,6 +79,7 @@ static const struct { {"quit-after-play", 'q', & options.quit_after_play, N_("Quit on playback stop")}, {"verbose", 'V', & options.verbose, N_("Print debugging messages (may be used twice)")}, #if defined(USE_QT) && defined(USE_GTK) + {"qt", 'Q', & options.qt, N_("Run in Qt mode")}, {"gtk", 'G', & options.gtk, N_("Run in GTK mode")}, #endif }; @@ -171,8 +173,16 @@ static bool parse_options (int argc, char * * argv) else if (options.verbose) audlog::set_stderr_level (audlog::Info); - if (options.gtk) + if (options.qt && options.gtk) { + fprintf (stderr, _("Conflicting options: --gtk and --qt\n")); + return false; + } + + if (options.qt) { + aud_set_mainloop_type (MainloopType::Qt); + } else { aud_set_mainloop_type (MainloopType::GLib); + } return true; } -- cgit v1.2.3 From 369960aeb71d04bf93e3a36a0bbdf9778cd962d9 Mon Sep 17 00:00:00 2001 From: Andrej Shadura Date: Wed, 6 Jan 2021 16:07:19 +0100 Subject: Import audacious_4.0.5.orig.tar.bz2 [dgit import orig audacious_4.0.5.orig.tar.bz2] --- .clang-format | 7 + .mailmap | 1 + .travis.yml | 15 + AUTHORS | 52 + COPYING | 64 + INSTALL | 365 + Makefile | 49 + acinclude.m4 | 235 + audacious.desktop | 101 + audacious.pc.in | 17 + autogen.sh | 4 + build-aux/config.guess | 1558 +++ build-aux/config.rpath | 690 ++ build-aux/config.sub | 1788 +++ build-aux/install-sh | 527 + buildsys.mk.in | 956 ++ config.h.in | 142 + configure | 11888 +++++++++++++++++++ configure.ac | 138 + contrib/audacious.appdata.xml | 31 + contrib/macpack/Audacious.app/Contents/Info.plist | 30 + .../macpack/Audacious.app/Contents/MacOS/audacious | 1 + contrib/macpack/Audacious.app/Contents/PkgInfo | 1 + .../Contents/Resources/Audacious.icns | Bin 0 -> 63527 bytes contrib/thunar-sendto-audacious-playlist.desktop | 19 + contrib/xchat-audacious.py | 125 + extra.mk.in | 21 + images/Makefile | 11 + images/README-svg | 19 + images/about-logo.svg | 1 + images/application-exit.svg | 1 + images/applications-graphics.svg | 1 + images/applications-internet.svg | 1 + images/applications-system.svg | 1 + images/appointment-new.svg | 1 + images/audacious.ico | Bin 0 -> 15086 bytes images/audacious.png | Bin 0 -> 976 bytes images/audacious.svg | 1 + images/audio-card.svg | 1 + images/audio-volume-high.svg | 1 + images/audio-volume-low.svg | 1 + images/audio-volume-medium.svg | 1 + images/audio-volume-muted.svg | 1 + images/audio-x-generic.svg | 1 + images/dialog-error.svg | 1 + images/dialog-information.svg | 1 + images/dialog-question.svg | 1 + images/dialog-warning.svg | 1 + images/document-new.svg | 1 + images/document-open-recent.svg | 1 + images/document-open.svg | 1 + images/document-save.svg | 1 + images/edit-clear.svg | 1 + images/edit-copy.svg | 1 + images/edit-cut.svg | 1 + images/edit-delete.svg | 1 + images/edit-find.svg | 1 + images/edit-paste.svg | 1 + images/edit-select-all.svg | 1 + images/face-smile.svg | 1 + images/folder-remote.svg | 1 + images/folder.svg | 1 + images/go-down.svg | 1 + images/go-jump.svg | 1 + images/go-next.svg | 1 + images/go-previous.svg | 1 + images/go-up.svg | 1 + images/help-about.svg | 1 + images/insert-text.svg | 1 + images/list-add.svg | 1 + images/list-remove.svg | 1 + images/media-optical.svg | 1 + images/media-playback-pause.svg | 1 + images/media-playback-start.svg | 1 + images/media-playback-stop.svg | 1 + images/media-playlist-repeat.svg | 1 + images/media-playlist-shuffle.svg | 1 + images/media-record.svg | 1 + images/media-skip-backward.svg | 1 + images/media-skip-forward.svg | 1 + images/meson.build | 2 + images/multimedia-volume-control.svg | 1 + images/preferences-desktop-font.svg | 1 + images/preferences-system.svg | 1 + images/process-stop.svg | 1 + images/system-run.svg | 1 + images/text-x-generic.svg | 1 + images/user-desktop.svg | 1 + images/user-home.svg | 1 + images/user-trash.svg | 1 + images/view-refresh.svg | 1 + images/view-sort-ascending.svg | 1 + images/view-sort-descending.svg | 1 + images/window-close.svg | 1 + m4/buildsys.m4 | 263 + man/Makefile | 3 + man/audacious.1.in | 166 + man/audtool.1.in | 389 + man/meson.build | 9 + meson.build | 154 + meson_options.txt | 4 + mkrelease.sh | 27 + po/LINGUAS | 42 + po/Makefile | 66 + po/POTFILES.in | 49 + po/ar.po | 1512 +++ po/audacious.pot | 1484 +++ po/be.po | 1512 +++ po/bg.po | 1513 +++ po/ca.po | 1512 +++ po/cmn.po | 1504 +++ po/cs.po | 1522 +++ po/da.po | 1503 +++ po/de.po | 1511 +++ po/el.po | 1515 +++ po/en@boldquot.header | 25 + po/en@quot.header | 22 + po/en_GB.po | 1502 +++ po/es.po | 1526 +++ po/es_AR.po | 1512 +++ po/es_MX.po | 1504 +++ po/et.po | 1505 +++ po/fi.po | 1510 +++ po/fr.po | 1512 +++ po/gl.po | 1506 +++ po/hu.po | 1513 +++ po/id_ID.po | 1524 +++ po/it.po | 1516 +++ po/ja.po | 1512 +++ po/ko.po | 1512 +++ po/lt.po | 1511 +++ po/lv.po | 1506 +++ po/meson.build | 15 + po/ml_IN.po | 1504 +++ po/ms.po | 1503 +++ po/nl.po | 1509 +++ po/pl.po | 1525 +++ po/process-transifex-po | 166 + po/pt_BR.po | 1528 +++ po/pt_PT.po | 1509 +++ po/ru.po | 1543 +++ po/si.po | 1505 +++ po/sk.po | 1517 +++ po/sr.po | 1507 +++ po/sr_RS.po | 1504 +++ po/sv.po | 1512 +++ po/ta.po | 1507 +++ po/tr.po | 1530 +++ po/uk.po | 1521 +++ po/update-potfiles.sh | 5 + po/zh_CN.po | 1510 +++ po/zh_TW.po | 1506 +++ src/Makefile | 33 + src/audacious/Makefile | 40 + src/audacious/audacious.manifest | 8 + src/audacious/audacious.rc | 7 + src/audacious/dbus-server.cc | 951 ++ src/audacious/main.cc | 408 + src/audacious/main.h | 46 + src/audacious/meson.build | 24 + src/audacious/signals.cc | 56 + src/audacious/util.cc | 48 + src/audacious/util.h | 29 + src/audtool/Makefile | 18 + src/audtool/audtool.h | 147 + src/audtool/handlers_equalizer.c | 123 + src/audtool/handlers_general.c | 200 + src/audtool/handlers_playback.c | 116 + src/audtool/handlers_playlist.c | 386 + src/audtool/handlers_playqueue.c | 104 + src/audtool/handlers_vitals.c | 129 + src/audtool/main.c | 275 + src/audtool/meson.build | 23 + src/audtool/report.c | 101 + src/audtool/wrappers.c | 193 + src/audtool/wrappers.h | 43 + src/config.h.meson | 21 + src/dbus/Makefile | 18 + src/dbus/aud-dbus.xml | 468 + src/dbus/meson.build | 29 + src/libaudcore/Makefile | 113 + src/libaudcore/adder.cc | 620 + src/libaudcore/art-search.cc | 153 + src/libaudcore/art.cc | 275 + src/libaudcore/audio.cc | 506 + src/libaudcore/audio.h.in | 139 + src/libaudcore/audstrings.cc | 1193 ++ src/libaudcore/audstrings.h | 130 + src/libaudcore/charset.cc | 213 + src/libaudcore/config.cc | 425 + src/libaudcore/cue-cache.cc | 94 + src/libaudcore/cue-cache.h | 41 + src/libaudcore/drct.cc | 279 + src/libaudcore/drct.h | 111 + src/libaudcore/effect.cc | 261 + src/libaudcore/equalizer-preset.cc | 233 + src/libaudcore/equalizer.cc | 227 + src/libaudcore/equalizer.h | 56 + src/libaudcore/eventqueue.cc | 125 + src/libaudcore/export.h | 33 + src/libaudcore/fft.cc | 123 + src/libaudcore/history.cc | 58 + src/libaudcore/hook.cc | 131 + src/libaudcore/hook.h | 174 + src/libaudcore/i18n.h | 45 + src/libaudcore/index.cc | 254 + src/libaudcore/index.h | 222 + src/libaudcore/inifile.cc | 125 + src/libaudcore/inifile.h | 44 + src/libaudcore/interface.cc | 244 + src/libaudcore/interface.h | 56 + src/libaudcore/internal.h | 164 + src/libaudcore/list.cc | 77 + src/libaudcore/list.h | 93 + src/libaudcore/logger.cc | 120 + src/libaudcore/mainloop.cc | 387 + src/libaudcore/mainloop.h | 67 + src/libaudcore/meson.build | 126 + src/libaudcore/multihash.cc | 179 + src/libaudcore/multihash.h | 339 + src/libaudcore/objects.h | 256 + src/libaudcore/output.cc | 842 ++ src/libaudcore/output.h | 51 + src/libaudcore/parse.cc | 50 + src/libaudcore/parse.h | 45 + src/libaudcore/playback.cc | 717 ++ src/libaudcore/playlist-cache.cc | 79 + src/libaudcore/playlist-data.cc | 1245 ++ src/libaudcore/playlist-data.h | 201 + src/libaudcore/playlist-files.cc | 189 + src/libaudcore/playlist-internal.h | 78 + src/libaudcore/playlist-utils.cc | 433 + src/libaudcore/playlist.cc | 1305 ++ src/libaudcore/playlist.h | 416 + src/libaudcore/plugin-init.cc | 401 + src/libaudcore/plugin-load.cc | 177 + src/libaudcore/plugin-registry.cc | 776 ++ src/libaudcore/plugin.h | 543 + src/libaudcore/plugins-internal.h | 71 + src/libaudcore/plugins.h | 75 + src/libaudcore/preferences.cc | 123 + src/libaudcore/preferences.h | 409 + src/libaudcore/probe-buffer.cc | 167 + src/libaudcore/probe-buffer.h | 71 + src/libaudcore/probe.cc | 267 + src/libaudcore/probe.h | 97 + src/libaudcore/ringbuf.cc | 198 + src/libaudcore/ringbuf.h | 172 + src/libaudcore/runtime.cc | 365 + src/libaudcore/runtime.h | 202 + src/libaudcore/scanner.cc | 128 + src/libaudcore/scanner.h | 71 + src/libaudcore/stringbuf.cc | 281 + src/libaudcore/strpool.cc | 201 + src/libaudcore/templates.h | 393 + src/libaudcore/tests/Makefile | 41 + src/libaudcore/tests/stubs.cc | 14 + src/libaudcore/tests/test-mainloop.cc | 140 + src/libaudcore/tests/test.cc | 531 + src/libaudcore/threads.h | 100 + src/libaudcore/timer.cc | 132 + src/libaudcore/tinylock.cc | 59 + src/libaudcore/tinylock.h | 43 + src/libaudcore/tuple-compiler.cc | 556 + src/libaudcore/tuple-compiler.h | 63 + src/libaudcore/tuple.cc | 881 ++ src/libaudcore/tuple.h | 236 + src/libaudcore/util.cc | 203 + src/libaudcore/vfs.cc | 448 + src/libaudcore/vfs.h | 194 + src/libaudcore/vfs_async.cc | 93 + src/libaudcore/vfs_async.h | 36 + src/libaudcore/vfs_local.cc | 406 + src/libaudcore/vfs_local.h | 46 + src/libaudcore/vis-runner.cc | 219 + src/libaudcore/visualization.cc | 177 + src/libaudcore/visualizer.h | 56 + src/libaudgui/Makefile | 67 + src/libaudgui/about.cc | 116 + src/libaudgui/confirm.cc | 98 + src/libaudgui/eq-preset.cc | 381 + src/libaudgui/equalizer.cc | 185 + src/libaudgui/file-opener.cc | 156 + src/libaudgui/images.gresource.xml | 67 + src/libaudgui/infopopup.cc | 334 + src/libaudgui/infowin.cc | 529 + src/libaudgui/init.cc | 387 + src/libaudgui/internal.h | 64 + src/libaudgui/jump-to-time.cc | 62 + src/libaudgui/jump-to-track-cache.cc | 214 + src/libaudgui/jump-to-track-cache.h | 46 + src/libaudgui/jump-to-track.cc | 345 + src/libaudgui/libaudgui-gtk.h | 95 + src/libaudgui/libaudgui.h | 101 + src/libaudgui/list.cc | 908 ++ src/libaudgui/list.h | 81 + src/libaudgui/menu.cc | 129 + src/libaudgui/menu.h | 83 + src/libaudgui/pixbufs.cc | 123 + src/libaudgui/playlists.cc | 227 + src/libaudgui/plugin-menu.cc | 118 + src/libaudgui/plugin-prefs.cc | 191 + src/libaudgui/plugin-view.cc | 250 + src/libaudgui/prefs-widget.cc | 644 + src/libaudgui/prefs-window.cc | 949 ++ src/libaudgui/preset-browser.cc | 132 + src/libaudgui/preset-browser.h | 30 + src/libaudgui/queue-manager.cc | 213 + src/libaudgui/scaled-image.cc | 101 + src/libaudgui/status.cc | 116 + src/libaudgui/urilist.cc | 88 + src/libaudgui/url-opener.cc | 114 + src/libaudgui/util.cc | 394 + src/libaudqt/Makefile | 64 + src/libaudqt/about-qt.cc | 107 + src/libaudqt/art-qt.cc | 82 + src/libaudqt/audqt.cc | 247 + src/libaudqt/colorbutton.cc | 62 + src/libaudqt/colorbutton.h | 52 + src/libaudqt/eq-preset-qt.cc | 414 + src/libaudqt/equalizer-qt.cc | 220 + src/libaudqt/export.h | 33 + src/libaudqt/file-entry.cc | 128 + src/libaudqt/fileopener.cc | 123 + src/libaudqt/font-entry.cc | 167 + src/libaudqt/iface.h | 63 + src/libaudqt/images.qrc | 66 + src/libaudqt/info-widget.cc | 425 + src/libaudqt/info-widget.h | 59 + src/libaudqt/infopopup-qt.cc | 202 + src/libaudqt/infowin-qt.cc | 297 + src/libaudqt/libaudqt-internal.h | 58 + src/libaudqt/libaudqt.h | 197 + src/libaudqt/log-inspector.cc | 285 + src/libaudqt/menu-qt.cc | 138 + src/libaudqt/menu.h | 122 + src/libaudqt/meson.build | 58 + src/libaudqt/playlist-management.cc | 106 + src/libaudqt/plugin-menu-qt.cc | 91 + src/libaudqt/prefs-builder.cc | 232 + src/libaudqt/prefs-plugin.cc | 164 + src/libaudqt/prefs-pluginlist-model.cc | 196 + src/libaudqt/prefs-pluginlist-model.h | 61 + src/libaudqt/prefs-widget-qt.cc | 431 + src/libaudqt/prefs-widget.h | 194 + src/libaudqt/prefs-window-qt.cc | 766 ++ src/libaudqt/queue-manager-qt.cc | 229 + src/libaudqt/treeview.cc | 123 + src/libaudqt/treeview.h | 49 + src/libaudqt/url-opener-qt.cc | 143 + src/libaudqt/util-qt.cc | 125 + src/libaudqt/volumebutton.cc | 188 + src/libaudtag/Makefile | 31 + src/libaudtag/ape/ape.cc | 419 + src/libaudtag/audtag.cc | 55 + src/libaudtag/audtag.h | 43 + src/libaudtag/builtin.h | 63 + src/libaudtag/id3/id3-common.cc | 334 + src/libaudtag/id3/id3-common.h | 36 + src/libaudtag/id3/id3v1.cc | 132 + src/libaudtag/id3/id3v22.cc | 294 + src/libaudtag/id3/id3v24.cc | 691 ++ src/libaudtag/meson.build | 27 + src/libaudtag/tag_module.cc | 92 + src/libaudtag/tag_module.h | 46 + src/libaudtag/util.cc | 175 + src/libaudtag/util.h | 158 + src/libguess/Makefile | 12 + src/libguess/dfa.c | 62 + src/libguess/dfa.h | 79 + src/libguess/guess.c | 54 + src/libguess/guess.scm | 623 + src/libguess/guess_impl.c | 656 + src/libguess/guess_tab.c | 1419 +++ src/libguess/libguess.h | 89 + src/libguess/meson.build | 15 + src/meson.build | 36 + win32/audacious.nsi.in | 129 + win32/merge.sh | 43 + win32/notes.html | 602 + win32/override/README.txt.in | 88 + win32/override/etc/gtk-2.0/gtkrc | 1 + .../share/icons/gnome/16x16/apps/audacious.png | Bin 0 -> 517 bytes win32/patches/atkprivate.c.diff | 17 + win32/patches/fluidsynth.diff | 36 + win32/patches/gdk-pixbuf-util.c.diff | 18 + win32/patches/gdkwindow-win32.c.diff | 15 + win32/patches/glib-2-52.diff | 168 + win32/patches/glib-gettext-fix.diff | 124 + win32/patches/gtk-parentheses.diff | 67 + win32/patches/gtkicontheme.c.diff | 28 + win32/patches/gtkmain.c.diff | 17 + win32/patches/libcddb-1.3.diff | 35 + win32/patches/libfaad-decoder.c.diff | 13 + win32/patches/libmms-strndup.diff | 44 + win32/patches/libmp3lame.sym.diff | 8 + win32/patches/libsamplerate-0.1.diff | 13 + win32/patches/neon-0.30.diff | 15 + win32/patches/wavpack-4.80.diff | 137 + 399 files changed, 134055 insertions(+) create mode 100644 .clang-format create mode 100644 .mailmap create mode 100644 .travis.yml create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 INSTALL create mode 100644 Makefile create mode 100644 acinclude.m4 create mode 100644 audacious.desktop create mode 100644 audacious.pc.in create mode 100755 autogen.sh create mode 100755 build-aux/config.guess create mode 100755 build-aux/config.rpath create mode 100755 build-aux/config.sub create mode 100755 build-aux/install-sh create mode 100644 buildsys.mk.in create mode 100644 config.h.in create mode 100755 configure create mode 100644 configure.ac create mode 100644 contrib/audacious.appdata.xml create mode 100644 contrib/macpack/Audacious.app/Contents/Info.plist create mode 120000 contrib/macpack/Audacious.app/Contents/MacOS/audacious create mode 100644 contrib/macpack/Audacious.app/Contents/PkgInfo create mode 100644 contrib/macpack/Audacious.app/Contents/Resources/Audacious.icns create mode 100644 contrib/thunar-sendto-audacious-playlist.desktop create mode 100644 contrib/xchat-audacious.py create mode 100644 extra.mk.in create mode 100644 images/Makefile create mode 100644 images/README-svg create mode 100644 images/about-logo.svg create mode 100644 images/application-exit.svg create mode 100644 images/applications-graphics.svg create mode 100644 images/applications-internet.svg create mode 100644 images/applications-system.svg create mode 100644 images/appointment-new.svg create mode 100644 images/audacious.ico create mode 100644 images/audacious.png create mode 100644 images/audacious.svg create mode 100644 images/audio-card.svg create mode 100644 images/audio-volume-high.svg create mode 100644 images/audio-volume-low.svg create mode 100644 images/audio-volume-medium.svg create mode 100644 images/audio-volume-muted.svg create mode 100644 images/audio-x-generic.svg create mode 100644 images/dialog-error.svg create mode 100644 images/dialog-information.svg create mode 100644 images/dialog-question.svg create mode 100644 images/dialog-warning.svg create mode 100644 images/document-new.svg create mode 100644 images/document-open-recent.svg create mode 100644 images/document-open.svg create mode 100644 images/document-save.svg create mode 100644 images/edit-clear.svg create mode 100644 images/edit-copy.svg create mode 100644 images/edit-cut.svg create mode 100644 images/edit-delete.svg create mode 100644 images/edit-find.svg create mode 100644 images/edit-paste.svg create mode 100644 images/edit-select-all.svg create mode 100644 images/face-smile.svg create mode 100644 images/folder-remote.svg create mode 100644 images/folder.svg create mode 100644 images/go-down.svg create mode 100644 images/go-jump.svg create mode 100644 images/go-next.svg create mode 100644 images/go-previous.svg create mode 100644 images/go-up.svg create mode 100644 images/help-about.svg create mode 100644 images/insert-text.svg create mode 100644 images/list-add.svg create mode 100644 images/list-remove.svg create mode 100644 images/media-optical.svg create mode 100644 images/media-playback-pause.svg create mode 100644 images/media-playback-start.svg create mode 100644 images/media-playback-stop.svg create mode 100644 images/media-playlist-repeat.svg create mode 100644 images/media-playlist-shuffle.svg create mode 100644 images/media-record.svg create mode 100644 images/media-skip-backward.svg create mode 100644 images/media-skip-forward.svg create mode 100644 images/meson.build create mode 100644 images/multimedia-volume-control.svg create mode 100644 images/preferences-desktop-font.svg create mode 100644 images/preferences-system.svg create mode 100644 images/process-stop.svg create mode 100644 images/system-run.svg create mode 100644 images/text-x-generic.svg create mode 100644 images/user-desktop.svg create mode 100644 images/user-home.svg create mode 100644 images/user-trash.svg create mode 100644 images/view-refresh.svg create mode 100644 images/view-sort-ascending.svg create mode 100644 images/view-sort-descending.svg create mode 100644 images/window-close.svg create mode 100644 m4/buildsys.m4 create mode 100644 man/Makefile create mode 100644 man/audacious.1.in create mode 100644 man/audtool.1.in create mode 100644 man/meson.build create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100755 mkrelease.sh create mode 100644 po/LINGUAS create mode 100644 po/Makefile create mode 100644 po/POTFILES.in create mode 100644 po/ar.po create mode 100644 po/audacious.pot create mode 100644 po/be.po create mode 100644 po/bg.po create mode 100644 po/ca.po create mode 100644 po/cmn.po create mode 100644 po/cs.po create mode 100644 po/da.po create mode 100644 po/de.po create mode 100644 po/el.po create mode 100644 po/en@boldquot.header create mode 100644 po/en@quot.header create mode 100644 po/en_GB.po create mode 100644 po/es.po create mode 100644 po/es_AR.po create mode 100644 po/es_MX.po create mode 100644 po/et.po create mode 100644 po/fi.po create mode 100644 po/fr.po create mode 100644 po/gl.po create mode 100644 po/hu.po create mode 100644 po/id_ID.po create mode 100644 po/it.po create mode 100644 po/ja.po create mode 100644 po/ko.po create mode 100644 po/lt.po create mode 100644 po/lv.po create mode 100644 po/meson.build create mode 100644 po/ml_IN.po create mode 100644 po/ms.po create mode 100644 po/nl.po create mode 100644 po/pl.po create mode 100755 po/process-transifex-po create mode 100644 po/pt_BR.po create mode 100644 po/pt_PT.po create mode 100644 po/ru.po create mode 100644 po/si.po create mode 100644 po/sk.po create mode 100644 po/sr.po create mode 100644 po/sr_RS.po create mode 100644 po/sv.po create mode 100644 po/ta.po create mode 100644 po/tr.po create mode 100644 po/uk.po create mode 100755 po/update-potfiles.sh create mode 100644 po/zh_CN.po create mode 100644 po/zh_TW.po create mode 100644 src/Makefile create mode 100644 src/audacious/Makefile create mode 100644 src/audacious/audacious.manifest create mode 100644 src/audacious/audacious.rc create mode 100644 src/audacious/dbus-server.cc create mode 100644 src/audacious/main.cc create mode 100644 src/audacious/main.h create mode 100644 src/audacious/meson.build create mode 100644 src/audacious/signals.cc create mode 100644 src/audacious/util.cc create mode 100644 src/audacious/util.h create mode 100644 src/audtool/Makefile create mode 100644 src/audtool/audtool.h create mode 100644 src/audtool/handlers_equalizer.c create mode 100644 src/audtool/handlers_general.c create mode 100644 src/audtool/handlers_playback.c create mode 100644 src/audtool/handlers_playlist.c create mode 100644 src/audtool/handlers_playqueue.c create mode 100644 src/audtool/handlers_vitals.c create mode 100644 src/audtool/main.c create mode 100644 src/audtool/meson.build create mode 100644 src/audtool/report.c create mode 100644 src/audtool/wrappers.c create mode 100644 src/audtool/wrappers.h create mode 100644 src/config.h.meson create mode 100644 src/dbus/Makefile create mode 100644 src/dbus/aud-dbus.xml create mode 100644 src/dbus/meson.build create mode 100644 src/libaudcore/Makefile create mode 100644 src/libaudcore/adder.cc create mode 100644 src/libaudcore/art-search.cc create mode 100644 src/libaudcore/art.cc create mode 100644 src/libaudcore/audio.cc create mode 100644 src/libaudcore/audio.h.in create mode 100644 src/libaudcore/audstrings.cc create mode 100644 src/libaudcore/audstrings.h create mode 100644 src/libaudcore/charset.cc create mode 100644 src/libaudcore/config.cc create mode 100644 src/libaudcore/cue-cache.cc create mode 100644 src/libaudcore/cue-cache.h create mode 100644 src/libaudcore/drct.cc create mode 100644 src/libaudcore/drct.h create mode 100644 src/libaudcore/effect.cc create mode 100644 src/libaudcore/equalizer-preset.cc create mode 100644 src/libaudcore/equalizer.cc create mode 100644 src/libaudcore/equalizer.h create mode 100644 src/libaudcore/eventqueue.cc create mode 100644 src/libaudcore/export.h create mode 100644 src/libaudcore/fft.cc create mode 100644 src/libaudcore/history.cc create mode 100644 src/libaudcore/hook.cc create mode 100644 src/libaudcore/hook.h create mode 100644 src/libaudcore/i18n.h create mode 100644 src/libaudcore/index.cc create mode 100644 src/libaudcore/index.h create mode 100644 src/libaudcore/inifile.cc create mode 100644 src/libaudcore/inifile.h create mode 100644 src/libaudcore/interface.cc create mode 100644 src/libaudcore/interface.h create mode 100644 src/libaudcore/internal.h create mode 100644 src/libaudcore/list.cc create mode 100644 src/libaudcore/list.h create mode 100644 src/libaudcore/logger.cc create mode 100644 src/libaudcore/mainloop.cc create mode 100644 src/libaudcore/mainloop.h create mode 100644 src/libaudcore/meson.build create mode 100644 src/libaudcore/multihash.cc create mode 100644 src/libaudcore/multihash.h create mode 100644 src/libaudcore/objects.h create mode 100644 src/libaudcore/output.cc create mode 100644 src/libaudcore/output.h create mode 100644 src/libaudcore/parse.cc create mode 100644 src/libaudcore/parse.h create mode 100644 src/libaudcore/playback.cc create mode 100644 src/libaudcore/playlist-cache.cc create mode 100644 src/libaudcore/playlist-data.cc create mode 100644 src/libaudcore/playlist-data.h create mode 100644 src/libaudcore/playlist-files.cc create mode 100644 src/libaudcore/playlist-internal.h create mode 100644 src/libaudcore/playlist-utils.cc create mode 100644 src/libaudcore/playlist.cc create mode 100644 src/libaudcore/playlist.h create mode 100644 src/libaudcore/plugin-init.cc create mode 100644 src/libaudcore/plugin-load.cc create mode 100644 src/libaudcore/plugin-registry.cc create mode 100644 src/libaudcore/plugin.h create mode 100644 src/libaudcore/plugins-internal.h create mode 100644 src/libaudcore/plugins.h create mode 100644 src/libaudcore/preferences.cc create mode 100644 src/libaudcore/preferences.h create mode 100644 src/libaudcore/probe-buffer.cc create mode 100644 src/libaudcore/probe-buffer.h create mode 100644 src/libaudcore/probe.cc create mode 100644 src/libaudcore/probe.h create mode 100644 src/libaudcore/ringbuf.cc create mode 100644 src/libaudcore/ringbuf.h create mode 100644 src/libaudcore/runtime.cc create mode 100644 src/libaudcore/runtime.h create mode 100644 src/libaudcore/scanner.cc create mode 100644 src/libaudcore/scanner.h create mode 100644 src/libaudcore/stringbuf.cc create mode 100644 src/libaudcore/strpool.cc create mode 100644 src/libaudcore/templates.h create mode 100644 src/libaudcore/tests/Makefile create mode 100644 src/libaudcore/tests/stubs.cc create mode 100644 src/libaudcore/tests/test-mainloop.cc create mode 100644 src/libaudcore/tests/test.cc create mode 100644 src/libaudcore/threads.h create mode 100644 src/libaudcore/timer.cc create mode 100644 src/libaudcore/tinylock.cc create mode 100644 src/libaudcore/tinylock.h create mode 100644 src/libaudcore/tuple-compiler.cc create mode 100644 src/libaudcore/tuple-compiler.h create mode 100644 src/libaudcore/tuple.cc create mode 100644 src/libaudcore/tuple.h create mode 100644 src/libaudcore/util.cc create mode 100644 src/libaudcore/vfs.cc create mode 100644 src/libaudcore/vfs.h create mode 100644 src/libaudcore/vfs_async.cc create mode 100644 src/libaudcore/vfs_async.h create mode 100644 src/libaudcore/vfs_local.cc create mode 100644 src/libaudcore/vfs_local.h create mode 100644 src/libaudcore/vis-runner.cc create mode 100644 src/libaudcore/visualization.cc create mode 100644 src/libaudcore/visualizer.h create mode 100644 src/libaudgui/Makefile create mode 100644 src/libaudgui/about.cc create mode 100644 src/libaudgui/confirm.cc create mode 100644 src/libaudgui/eq-preset.cc create mode 100644 src/libaudgui/equalizer.cc create mode 100644 src/libaudgui/file-opener.cc create mode 100644 src/libaudgui/images.gresource.xml create mode 100644 src/libaudgui/infopopup.cc create mode 100644 src/libaudgui/infowin.cc create mode 100644 src/libaudgui/init.cc create mode 100644 src/libaudgui/internal.h create mode 100644 src/libaudgui/jump-to-time.cc create mode 100644 src/libaudgui/jump-to-track-cache.cc create mode 100644 src/libaudgui/jump-to-track-cache.h create mode 100644 src/libaudgui/jump-to-track.cc create mode 100644 src/libaudgui/libaudgui-gtk.h create mode 100644 src/libaudgui/libaudgui.h create mode 100644 src/libaudgui/list.cc create mode 100644 src/libaudgui/list.h create mode 100644 src/libaudgui/menu.cc create mode 100644 src/libaudgui/menu.h create mode 100644 src/libaudgui/pixbufs.cc create mode 100644 src/libaudgui/playlists.cc create mode 100644 src/libaudgui/plugin-menu.cc create mode 100644 src/libaudgui/plugin-prefs.cc create mode 100644 src/libaudgui/plugin-view.cc create mode 100644 src/libaudgui/prefs-widget.cc create mode 100644 src/libaudgui/prefs-window.cc create mode 100644 src/libaudgui/preset-browser.cc create mode 100644 src/libaudgui/preset-browser.h create mode 100644 src/libaudgui/queue-manager.cc create mode 100644 src/libaudgui/scaled-image.cc create mode 100644 src/libaudgui/status.cc create mode 100644 src/libaudgui/urilist.cc create mode 100644 src/libaudgui/url-opener.cc create mode 100644 src/libaudgui/util.cc create mode 100644 src/libaudqt/Makefile create mode 100644 src/libaudqt/about-qt.cc create mode 100644 src/libaudqt/art-qt.cc create mode 100644 src/libaudqt/audqt.cc create mode 100644 src/libaudqt/colorbutton.cc create mode 100644 src/libaudqt/colorbutton.h create mode 100644 src/libaudqt/eq-preset-qt.cc create mode 100644 src/libaudqt/equalizer-qt.cc create mode 100644 src/libaudqt/export.h create mode 100644 src/libaudqt/file-entry.cc create mode 100644 src/libaudqt/fileopener.cc create mode 100644 src/libaudqt/font-entry.cc create mode 100644 src/libaudqt/iface.h create mode 100644 src/libaudqt/images.qrc create mode 100644 src/libaudqt/info-widget.cc create mode 100644 src/libaudqt/info-widget.h create mode 100644 src/libaudqt/infopopup-qt.cc create mode 100644 src/libaudqt/infowin-qt.cc create mode 100644 src/libaudqt/libaudqt-internal.h create mode 100644 src/libaudqt/libaudqt.h create mode 100644 src/libaudqt/log-inspector.cc create mode 100644 src/libaudqt/menu-qt.cc create mode 100644 src/libaudqt/menu.h create mode 100644 src/libaudqt/meson.build create mode 100644 src/libaudqt/playlist-management.cc create mode 100644 src/libaudqt/plugin-menu-qt.cc create mode 100644 src/libaudqt/prefs-builder.cc create mode 100644 src/libaudqt/prefs-plugin.cc create mode 100644 src/libaudqt/prefs-pluginlist-model.cc create mode 100644 src/libaudqt/prefs-pluginlist-model.h create mode 100644 src/libaudqt/prefs-widget-qt.cc create mode 100644 src/libaudqt/prefs-widget.h create mode 100644 src/libaudqt/prefs-window-qt.cc create mode 100644 src/libaudqt/queue-manager-qt.cc create mode 100644 src/libaudqt/treeview.cc create mode 100644 src/libaudqt/treeview.h create mode 100644 src/libaudqt/url-opener-qt.cc create mode 100644 src/libaudqt/util-qt.cc create mode 100644 src/libaudqt/volumebutton.cc create mode 100644 src/libaudtag/Makefile create mode 100644 src/libaudtag/ape/ape.cc create mode 100644 src/libaudtag/audtag.cc create mode 100644 src/libaudtag/audtag.h create mode 100644 src/libaudtag/builtin.h create mode 100644 src/libaudtag/id3/id3-common.cc create mode 100644 src/libaudtag/id3/id3-common.h create mode 100644 src/libaudtag/id3/id3v1.cc create mode 100644 src/libaudtag/id3/id3v22.cc create mode 100644 src/libaudtag/id3/id3v24.cc create mode 100644 src/libaudtag/meson.build create mode 100644 src/libaudtag/tag_module.cc create mode 100644 src/libaudtag/tag_module.h create mode 100644 src/libaudtag/util.cc create mode 100644 src/libaudtag/util.h create mode 100644 src/libguess/Makefile create mode 100644 src/libguess/dfa.c create mode 100644 src/libguess/dfa.h create mode 100644 src/libguess/guess.c create mode 100644 src/libguess/guess.scm create mode 100644 src/libguess/guess_impl.c create mode 100644 src/libguess/guess_tab.c create mode 100644 src/libguess/libguess.h create mode 100644 src/libguess/meson.build create mode 100644 src/meson.build create mode 100644 win32/audacious.nsi.in create mode 100644 win32/merge.sh create mode 100755 win32/notes.html create mode 100644 win32/override/README.txt.in create mode 100644 win32/override/etc/gtk-2.0/gtkrc create mode 100644 win32/override/share/icons/gnome/16x16/apps/audacious.png create mode 100644 win32/patches/atkprivate.c.diff create mode 100644 win32/patches/fluidsynth.diff create mode 100644 win32/patches/gdk-pixbuf-util.c.diff create mode 100644 win32/patches/gdkwindow-win32.c.diff create mode 100644 win32/patches/glib-2-52.diff create mode 100644 win32/patches/glib-gettext-fix.diff create mode 100644 win32/patches/gtk-parentheses.diff create mode 100644 win32/patches/gtkicontheme.c.diff create mode 100644 win32/patches/gtkmain.c.diff create mode 100644 win32/patches/libcddb-1.3.diff create mode 100644 win32/patches/libfaad-decoder.c.diff create mode 100644 win32/patches/libmms-strndup.diff create mode 100644 win32/patches/libmp3lame.sym.diff create mode 100644 win32/patches/libsamplerate-0.1.diff create mode 100644 win32/patches/neon-0.30.diff create mode 100644 win32/patches/wavpack-4.80.diff diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..9c546c4 --- /dev/null +++ b/.clang-format @@ -0,0 +1,7 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +AccessModifierOffset: -4 +BreakBeforeBraces: Allman +PointerAlignment: Middle +SpaceAfterTemplateKeyword: false +AlwaysBreakTemplateDeclarations: Yes diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000..28c0689 --- /dev/null +++ b/.mailmap @@ -0,0 +1 @@ +Ariadne Conill diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..fea03d3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +language: + - cpp +compiler: + - gcc + - clang +before_install: + - sudo apt-get -qq update + - sudo apt-get install libgtk2.0-dev qtbase5-dev +script: + - ./autogen.sh + - ./configure --prefix=/opt/aud --enable-gtk + - make + - cd src/libaudcore/tests + - make test + - ./test diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..f2a9d98 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,52 @@ +HISTORY + +Audacious was originally based on the X Multimedia System (“XMMS”) via its +GTK+ 2.x port Beep Media Player (“BMP”). Audacious has changed quite a bit +since its first release, however, and little XMMS/BMP code remains. + +The Audacious project began in 2005 under the leadership of Ariadne Conill +(“kaniini”). Many people have made contributions, both large and small, since +that time. At present, the project is led by John Lindgren and Michał Lipski +(“tallica”), with help from a few others. Special thanks go to Michał Lipski +for setting up and maintaining the current website, and to Thomas Lange for +leading the translation effort. + +The Audacious logo was designed by George Averill and updated by John Lindgren. +It uses the “Circulate” font created by Brian Kent. + +Besides the developers listed below, a word of thanks is also due to the many +people who have helped to translate the Audacious interface into a number of +different (human) languages. The translation effort is now done mostly through +Transifex, making it easier to contribute but also nearly impossible to +maintain a list of those who have done so. + + +DEVELOPERS + +Audacious was written by: + + George Averill + Daniel Barkalow + René Bertin + Christian Birchinger + Ariadne Conill + Ralf Ertzinger + Michael Färber + Matti Hämäläinen + Michael Hanselmann + Anders Johansson + Jussi Judin + Thomas Lange + John Lindgren + Michał Lipski + Giacomo Lozito + Mikael Magnusson + Tomasz Moń + Paula Stanciu + Ben Tucker + Tony Vroon + Yoshiki Yazawa + Eugene Zagidullin + +Please note that many of Audacious’s features are implemented by plugins, +whose authors are listed elsewhere. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..ff618fb --- /dev/null +++ b/COPYING @@ -0,0 +1,64 @@ +LICENSE + +Copyright © 2001-2020 Audacious developers and others + +(A list of the copyright holders is provided in the AUTHORS file.) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the + documentation provided with the distribution. + + This software is provided “as is” and without any warranty, express or + implied. In no event shall the authors be liable for any damages arising + from the use of this software. + +EXCEPTIONS + +Audacious includes icons adapted from the Paper Icon Set by Sam Hewitt. These +icons are distributed under the Creative Commons Attribution-ShareAlike 4.0 +license (see https://creativecommons.org/licenses/by-sa/4.0/). + +Please note that many of the plugins distributed with Audacious are under +different licenses. + +THIRD-PARTY LICENSES + +libguess - a high-speed character set detection library + + Copyright © 2000-2003 Shiro Kawai + Copyright © 2005-2010 Yoshiki Yazawa + Copyright © 2007-2010 William Pitcock + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the authors nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + + This software is provided by the copyright holders and contributors “as is” + and any express or implied warranties, including, but not limited to, the + implied warranties of merchantability and fitness for a particular purpose + are disclaimed. In no event shall the copyright owner or contributors be + liable for any direct, indirect, incidental, special, exemplary, or + consequential damages (including, but not limited to, procurement of + substitute goods or services; loss of use, data, or profits; or business + interruption) however caused and on any theory of liability, whether in + contract, strict liability, or tort (including negligence or otherwise) + arising in any way out of the use of this software, even if advised of the + possibility of such damage. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..7d1c323 --- /dev/null +++ b/INSTALL @@ -0,0 +1,365 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d309f73 --- /dev/null +++ b/Makefile @@ -0,0 +1,49 @@ +SUBDIRS = src man images po + +DISTCLEAN = ${GENERATED_FILES} config.h config.log config.status + +DATA = AUTHORS COPYING + +include buildsys.mk +include extra.mk + +install-extra: + for i in audacious.pc; do \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${pkgconfigdir} && ${INSTALL} -m 644 $$i ${DESTDIR}${pkgconfigdir}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi; \ + done + for i in audacious.desktop; do \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${datarootdir}/applications && ${INSTALL} -m 644 $$i ${DESTDIR}${datarootdir}/applications/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + if [ -f ${DESTDIR}${datadir}/audacious/Skins/Default/balance.png ]; then \ + rm -f ${DESTDIR}${datadir}/audacious/Skins/Default/balance.png; \ + fi + +uninstall-extra: + for i in audacious.pc; do \ + if [ -f ${DESTDIR}${pkgconfigdir}/$$i ]; then \ + if rm -f ${DESTDIR}${pkgconfigdir}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi; \ + done + for i in audacious.desktop; do \ + if test -f ${DESTDIR}${datarootdir}/applications/$$i; then \ + if rm -f ${DESTDIR}${datarootdir}/applications/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..5f4fba2 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,235 @@ +dnl Backward compatibility with older pkg-config <= 0.28 +dnl Retrieves the value of the pkg-config variable +dnl for the given module. +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ==================================================== +m4_ifndef([PKG_CHECK_VAR], [ +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +]) +]) + + +dnl Add $1 to CFLAGS and CXXFLAGS if supported +dnl ========================================== + +AC_DEFUN([AUD_CHECK_CFLAGS],[ + AC_MSG_CHECKING([whether the C/C++ compiler supports $1]) + OLDCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $1 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[return 0;])],[ + AC_MSG_RESULT(yes) + CFLAGS="$OLDCFLAGS $1" + CXXFLAGS="$CXXFLAGS $1" + ],[ + AC_MSG_RESULT(no) + CFLAGS="$OLDCFLAGS" + ]) +]) + +dnl Add $1 to CXXFLAGS if supported +dnl =============================== + +AC_DEFUN([AUD_CHECK_CXXFLAGS],[ + AC_MSG_CHECKING([whether the C++ compiler supports $1]) + AC_LANG_PUSH([C++]) + OLDCXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $1 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[return 0;])],[ + AC_MSG_RESULT(yes) + CXXFLAGS="$OLDCXXFLAGS $1" + ],[ + AC_MSG_RESULT(no) + CXXFLAGS="$OLDCXXFLAGS" + ]) + AC_LANG_POP([C++]) +]) + + +dnl ** +dnl ** Common checks +dnl ** +AC_DEFUN([AUD_COMMON_PROGS], [ + +dnl Check platform +dnl ============== + +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +AC_MSG_CHECKING([operating system type]) + +HAVE_LINUX=no +HAVE_MSWINDOWS=no +HAVE_DARWIN=no + +case "$target" in + *linux*) + AC_MSG_RESULT(Linux) + HAVE_LINUX=yes + ;; + *mingw*) + AC_MSG_RESULT(Windows) + HAVE_MSWINDOWS=yes + ;; + *darwin*) + AC_MSG_RESULT(Darwin) + HAVE_DARWIN=yes + ;; + *) + AC_MSG_RESULT(other UNIX) + ;; +esac + +AC_SUBST(HAVE_MSWINDOWS) +AC_SUBST(HAVE_LINUX) +AC_SUBST(HAVE_DARWIN) + +dnl Check for C and C++ compilers +dnl ============================= +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([AC_C_BIGENDIAN]) +AC_REQUIRE([AC_SYS_LARGEFILE]) + +if test "x$GCC" = "xyes"; then + CFLAGS="$CFLAGS -std=gnu99 -ffast-math -Wall -pipe" + if test "x$HAVE_DARWIN" = "xyes"; then + CXXFLAGS="$CXXFLAGS -std=gnu++11 -ffast-math -Wall -pipe" + LDFLAGS="$LDFLAGS" + else + CXXFLAGS="$CXXFLAGS -std=gnu++11 -ffast-math -Wall -pipe" + fi + AUD_CHECK_CFLAGS(-Wtype-limits) + AUD_CHECK_CFLAGS(-Wno-stringop-truncation) + AUD_CHECK_CXXFLAGS(-Woverloaded-virtual) +fi + +dnl On Mac, check for Objective-C and -C++ compilers +dnl ================================================ + +if test "x$HAVE_DARWIN" = "xyes"; then + AC_PROG_OBJC + AC_PROG_OBJCPP + AC_PROG_OBJCXX + AC_PROG_OBJCXXCPP + + OBJCXXFLAGS="$OBJCXXFLAGS -std=c++11" +fi + +dnl Enable "-Wl,-z,defs" only on Linux +dnl ================================== +if test $HAVE_LINUX = yes ; then + LDFLAGS="$LDFLAGS -Wl,-z,defs" +fi + +dnl MinGW-specific flags +dnl ==================== +if test $HAVE_MSWINDOWS = yes ; then + AC_DEFINE([__USE_MINGW_ANSI_STDIO], [1], "Use GNU-style printf") + CFLAGS="$CFLAGS -march=i686" +fi + +dnl Byte order +dnl ========== +AC_C_BIGENDIAN([BIGENDIAN=1], [BIGENDIAN=0], + [AC_MSG_ERROR([Unknown machine byte order])], + [AC_MSG_ERROR([Universal builds are not supported, sorry])]) +AC_SUBST([BIGENDIAN]) + +dnl Prevent symbol collisions +dnl ========================= +if test "x$HAVE_MSWINDOWS" = "xyes" ; then + EXPORT="__declspec(dllexport)" +elif test "x$GCC" = "xyes" ; then + CFLAGS="$CFLAGS -fvisibility=hidden" + CXXFLAGS="$CXXFLAGS -fvisibility=hidden" + EXPORT="__attribute__((visibility(\"default\")))" +else + AC_MSG_ERROR([Unknown syntax for EXPORT keyword]) +fi +AC_DEFINE_UNQUOTED([EXPORT], [$EXPORT], [Define to compiler syntax for public symbols]) + +dnl Checks for various programs +dnl =========================== +AC_PROG_LN_S +AC_PATH_PROG([RM], [rm]) +AC_PATH_PROG([MV], [mv]) +AC_PATH_PROG([CP], [cp]) +AC_PATH_TOOL([AR], [ar]) +AC_PATH_TOOL([RANLIB], [ranlib]) +AC_PATH_TOOL([WINDRES], [windres]) + +dnl Check for POSIX threads +dnl ======================= +AC_SEARCH_LIBS([pthread_create], [pthread]) + +dnl Check for GTK+ and pals +dnl ======================= + +PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.32) +PKG_CHECK_MODULES(GMODULE, gmodule-2.0 >= 2.32) + +AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_32], [target GLib 2.32]) + +dnl GTK+ support +dnl ============= + +AC_ARG_ENABLE(gtk, + AS_HELP_STRING(--enable-gtk, [Enable GTK+ support (default=disabled)]), + USE_GTK=$enableval, USE_GTK=no) + +if test $USE_GTK = yes ; then + PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.24) + AC_DEFINE([USE_GTK], [1], [Define if GTK+ support enabled]) +fi + +AC_SUBST(USE_GTK) + +if test $HAVE_MSWINDOWS = yes ; then + PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.32) +else + PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.32 gio-unix-2.0 >= 2.32) +fi + +AC_SUBST(GLIB_CFLAGS) +AC_SUBST(GLIB_LIBS) +AC_SUBST(GIO_CFLAGS) +AC_SUBST(GIO_LIBS) +AC_SUBST(GMODULE_CFLAGS) +AC_SUBST(GMODULE_LIBS) +AC_SUBST(GTK_CFLAGS) +AC_SUBST(GTK_LIBS) + +dnl Qt support +dnl ========== + +AC_ARG_ENABLE(qt, + AS_HELP_STRING(--disable-qt, [Disable Qt support (default=enabled)]), + USE_QT=$enableval, USE_QT=yes) + +if test $USE_QT = yes ; then + PKG_CHECK_MODULES([QTCORE], [Qt5Core >= 5.2]) + PKG_CHECK_VAR([QTBINPATH], [Qt5Core >= 5.2], [host_bins]) + PKG_CHECK_MODULES([QT], [Qt5Core Qt5Gui Qt5Widgets >= 5.2]) + AC_DEFINE([USE_QT], [1], [Define if Qt support enabled]) + AC_DEFINE([QT_NO_DEPRECATED_WARNINGS], [1], [Qt 6 is not supported yet]) + + # needed if Qt was built with -reduce-relocations + QTCORE_CFLAGS="$QTCORE_CFLAGS -fPIC" + QT_CFLAGS="$QT_CFLAGS -fPIC" +fi + +AC_SUBST(USE_QT) +AC_SUBST(QT_CFLAGS) +AC_SUBST(QT_LIBS) +AC_SUBST(QTBINPATH) + +]) diff --git a/audacious.desktop b/audacious.desktop new file mode 100644 index 0000000..804b27c --- /dev/null +++ b/audacious.desktop @@ -0,0 +1,101 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=Audacious +GenericName=Music Player +Comment=Listen to music +Icon=audacious +Categories=AudioVideo;Audio;Player; +Exec=audacious %U +TryExec=audacious +StartupNotify=false +Terminal=false +MimeType=application/ogg;application/x-cue;application/x-ogg;application/xspf+xml;audio/aac;audio/flac;audio/midi;audio/mp3;audio/mp4;audio/mpeg;audio/mpegurl;audio/ogg;audio/prs.sid;audio/wav;audio/x-flac;audio/x-it;audio/x-mod;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-asx;audio/x-ms-wma;audio/x-musepack;audio/x-s3m;audio/x-scpls;audio/x-stm;audio/x-vorbis+ogg;audio/x-wav;audio/x-wavpack;audio/x-xm;x-content/audio-cdda; + +Comment[ar]=استمع إلى الموسيقى +Comment[be]=Слухайце музыку +Comment[bg]=Слушане на музика +Comment[ca]=Escolteu música +Comment[cs]=Poslouchat hudbu +Comment[da]=Lyt til musik +Comment[de]=Musik hören +Comment[el]=Ακρόαση μουσικής +Comment[eo]=Aŭskulti muzikon +Comment[es_AR]=Escuchar música +Comment[es_CL]=Listado de musica +Comment[es_MX]=Escuchar la música +Comment[es]=Escuchar música +Comment[et]=Kuula muusikat +Comment[fa_IR]=به موسیقی گوش کنید +Comment[fi]=Kuuntele musiikkia +Comment[fr]=Écouter de la musique +Comment[gl]=Escoitar música +Comment[hr]=Slušanje glazbe +Comment[hu]=Zenehallgatás +Comment[id_ID]=Dengarkan musik +Comment[it]=Ascolta la musica +Comment[ja]=音楽を聴きます +Comment[ko]=음악을 들어요 +Comment[lt]=Klausyti muzikos +Comment[lv]=Klausīties mūziku +Comment[ms]=Dengar muzik +Comment[nl]=Luister naar muziek +Comment[pl]=Słuchaj muzyki +Comment[pt_BR]=Ouça música +Comment[pt_PT]=Reprodução de músicas +Comment[pt]=Escuta musica +Comment[ro]=Ascultă muzică +Comment[ru]=Слушать музыку +Comment[sk]=Počúvajte hudbu +Comment[sr]=Слушајте музику +Comment[sv]=Lyssna på musik +Comment[ta]=இசையைக் கேளுங்கள் +Comment[tr]=Müzik dinleyin +Comment[uk]=Слухати музику +Comment[vi]=Nghe nhạc +Comment[zh_CN]=聆听音乐 +Comment[zh_TW]=音樂鑑賞 + +GenericName[ar]=مشغل الموسيقى +GenericName[be]=Музычны прайгравальнік +GenericName[bg]=Музикален плейър +GenericName[ca]=Reproductor de música +GenericName[cs]=Hudební přehrávač +GenericName[da]=Musikafspiller +GenericName[de]=Musikspieler +GenericName[el]=Πρόγραμμα αναπαραγωγής μουσικής +GenericName[eo]=Muzik-ludilo +GenericName[es_AR]=Reproductor de Música +GenericName[es_CL]=Reproductor de musica +GenericName[es_MX]=Reproductor de Música +GenericName[es]=Reproductor de música +GenericName[et]=Muusikaesitaja +GenericName[fa_IR]=پخش کننده موسیقی +GenericName[fi]=Musiikkisoitin +GenericName[fr]=Lecteur audio +GenericName[gl]=Reprodutor de música +GenericName[hr]=Svirač glazbe +GenericName[hu]=Zenelejátszó +GenericName[id_ID]=Pemutar musik +GenericName[it]=Lettore musicale +GenericName[ja]=音楽プレイヤー +GenericName[ko]=음악 재생기 +GenericName[lt]=Muzikos grotuvas +GenericName[lv]=Mūzikas atskaņotājs +GenericName[ms]=Pemain Muzik +GenericName[nl]=Muziekspeler +GenericName[pl]=Odtwarzacz muzyczny +GenericName[pt_BR]=Reprodutor de Música +GenericName[pt_PT]=Reprodutor áudio +GenericName[pt]=Reprodutor de musica +GenericName[ro]=Player de muzică +GenericName[ru]=Музыкальный проигрыватель +GenericName[sk]=Hudobný prehrávač +GenericName[sr]=Програм за слушање музике +GenericName[sv]=Musikspelare +GenericName[ta]=இசைப்பான் +GenericName[tr]=Müzik Çalar +GenericName[uk]=Музичний програвач +GenericName[vi]=Trình chơi nhạc +GenericName[zh_CN]=音乐播放器 +GenericName[zh_TW]=音樂播放器 diff --git a/audacious.pc.in b/audacious.pc.in new file mode 100644 index 0000000..fe092fd --- /dev/null +++ b/audacious.pc.in @@ -0,0 +1,17 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +datarootdir=@datarootdir@ +data_dir=@datadir@/audacious + +version=@PACKAGE_VERSION@ +include_dir=@includedir@ +audacious_include_dir=@includedir@ +lib_dir=@libdir@ + +plugin_dir=@plugindir@ + +Name: Audacious +Description: Audacious is a versatile and handy multi platform media player +Version: @PACKAGE_VERSION@ +Libs: -L${lib_dir} -laudcore +Cflags: -I${audacious_include_dir} diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..14657bc --- /dev/null +++ b/autogen.sh @@ -0,0 +1,4 @@ +#!/bin/sh +aclocal -I m4 || exit 1 +autoconf || exit 1 +autoheader || exit 1 diff --git a/build-aux/config.guess b/build-aux/config.guess new file mode 100755 index 0000000..b79252d --- /dev/null +++ b/build-aux/config.guess @@ -0,0 +1,1558 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2013 Free Software Foundation, Inc. + +timestamp='2013-06-10' + +# This file 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 3 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, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2013 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/build-aux/config.rpath b/build-aux/config.rpath new file mode 100755 index 0000000..c38b914 --- /dev/null +++ b/build-aux/config.rpath @@ -0,0 +1,690 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2013 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's _LT_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + ecc*) + wl='-Wl,' + ;; + icc* | ifort*) + wl='-Wl,' + ;; + lf95*) + wl='-Wl,' + ;; + nagfor*) + wl='-Wl,-Wl,,' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + xl* | bgxl* | bgf* | mpixl*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + wl= + ;; + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + newsos6) + ;; + *nto* | *qnx*) + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + rdos*) + ;; + solaris*) + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + wl='-Qoption ld ' + ;; + *) + wl='-Wl,' + ;; + esac + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + wl='-Wl,' + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's _LT_LINKER_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32* | cegcc*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + haiku*) + ;; + interix[3-9]*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + hardcode_direct=no + if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then + : + else + ld_shlibs=no + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd2.2*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + freebsd2*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + ;; + *) + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + *nto* | *qnx*) + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. +# Unlike libtool.m4, here we don't care about _all_ names of the library, but +# only about the one the linker finds when passed -lNAME. This is the last +# element of library_names_spec in libtool.m4, or possibly two of them if the +# linker has special search rules. +library_names_spec= # the last element of library_names_spec in libtool.m4 +libname_spec='lib$name' +case "$host_os" in + aix3*) + library_names_spec='$libname.a' + ;; + aix[4-9]*) + library_names_spec='$libname$shrext' + ;; + amigaos*) + case "$host_cpu" in + powerpc*) + library_names_spec='$libname$shrext' ;; + m68k) + library_names_spec='$libname.a' ;; + esac + ;; + beos*) + library_names_spec='$libname$shrext' + ;; + bsdi[45]*) + library_names_spec='$libname$shrext' + ;; + cygwin* | mingw* | pw32* | cegcc*) + shrext=.dll + library_names_spec='$libname.dll.a $libname.lib' + ;; + darwin* | rhapsody*) + shrext=.dylib + library_names_spec='$libname$shrext' + ;; + dgux*) + library_names_spec='$libname$shrext' + ;; + freebsd* | dragonfly*) + case "$host_os" in + freebsd[123]*) + library_names_spec='$libname$shrext$versuffix' ;; + *) + library_names_spec='$libname$shrext' ;; + esac + ;; + gnu*) + library_names_spec='$libname$shrext' + ;; + haiku*) + library_names_spec='$libname$shrext' + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + library_names_spec='$libname$shrext' + ;; + interix[3-9]*) + library_names_spec='$libname$shrext' + ;; + irix5* | irix6* | nonstopux*) + library_names_spec='$libname$shrext' + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + library_names_spec='$libname$shrext' + ;; + knetbsd*-gnu) + library_names_spec='$libname$shrext' + ;; + netbsd*) + library_names_spec='$libname$shrext' + ;; + newsos6) + library_names_spec='$libname$shrext' + ;; + *nto* | *qnx*) + library_names_spec='$libname$shrext' + ;; + openbsd*) + library_names_spec='$libname$shrext$versuffix' + ;; + os2*) + libname_spec='$name' + shrext=.dll + library_names_spec='$libname.a' + ;; + osf3* | osf4* | osf5*) + library_names_spec='$libname$shrext' + ;; + rdos*) + ;; + solaris*) + library_names_spec='$libname$shrext' + ;; + sunos4*) + library_names_spec='$libname$shrext$versuffix' + ;; + sysv4 | sysv4.3*) + library_names_spec='$libname$shrext' + ;; + sysv4*MP*) + library_names_spec='$libname$shrext' + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + library_names_spec='$libname$shrext' + ;; + tpf*) + library_names_spec='$libname$shrext' + ;; + uts4*) + library_names_spec='$libname$shrext' + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2013 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 \ + | or1k | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or1k-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/build-aux/install-sh b/build-aux/install-sh new file mode 100755 index 0000000..377bb86 --- /dev/null +++ b/build-aux/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-11-20.07; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/buildsys.mk.in b/buildsys.mk.in new file mode 100644 index 0000000..e364ba8 --- /dev/null +++ b/buildsys.mk.in @@ -0,0 +1,956 @@ +# +# Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, +# 2017 +# Jonathan Schleifer +# +# https://heap.zone/git/?p=buildsys.git +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice is present in all copies. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +AS = @AS@ +CC = @CC@ +CXX = @CXX@ +CPP = @CPP@ +DC = @DC@ +ERLC = @ERLC@ +OBJC = @OBJC@ +OBJCXX = @OBJCXX@ +AR = @AR@ +LD = ${CC} +RANLIB = @RANLIB@ +PYTHON = @PYTHON@ +ASFLAGS = @ASFLAGS@ +CFLAGS = @CFLAGS@ +CXXFLAGS = @CXXFLAGS@ +CPPFLAGS = @CPPFLAGS@ +DFLAGS = @DFLAGS@ +ERLCFLAGS = @ERLCFLAGS@ +OBJCFLAGS = @OBJCFLAGS@ +OBJCXXFLAGS = @OBJCXXFLAGS@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_RPATH = @LDFLAGS_RPATH@ +LIBS = @LIBS@ +PYTHON_FLAGS = @PYTHON_FLAGS@ +PROG_IMPLIB_NEEDED = @PROG_IMPLIB_NEEDED@ +PROG_IMPLIB_LDFLAGS = @PROG_IMPLIB_LDFLAGS@ +PROG_SUFFIX = @EXEEXT@ +LIB_CFLAGS = @LIB_CFLAGS@ +LIB_LDFLAGS = @LIB_LDFLAGS@ +LIB_LDFLAGS_INSTALL_NAME = @LIB_LDFLAGS_INSTALL_NAME@ +LIB_PREFIX = @LIB_PREFIX@ +LIB_SUFFIX = @LIB_SUFFIX@ +PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ +PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ +PLUGIN_SUFFIX = @PLUGIN_SUFFIX@ +FRAMEWORK_LDFLAGS = @FRAMEWORK_LDFLAGS@ +FRAMEWORK_LDFLAGS_INSTALL_NAME = @FRAMEWORK_LDFLAGS_INSTALL_NAME@ +CODESIGN = @CODESIGN@ +CODESIGN_IDENTITY ?= - +INSTALL_LIB = @INSTALL_LIB@ +UNINSTALL_LIB = @UNINSTALL_LIB@ +CLEAN_LIB = @CLEAN_LIB@ +AS_DEPENDS = @AS_DEPENDS@ +CC_DEPENDS = @CC_DEPENDS@ +CXX_DEPENDS = @CXX_DEPENDS@ +OBJC_DEPENDS = @OBJC_DEPENDS@ +OBJCXX_DEPENDS = @OBJCXX_DEPENDS@ +LN_S = @LN_S@ +MKDIR_P = mkdir -p +INSTALL = @INSTALL@ -p +SHELL = @SHELL@ +MSGFMT = @MSGFMT@ +JAVAC = @JAVAC@ +JAVACFLAGS = @JAVACFLAGS@ +JAR = @JAR@ +WINDRES = @WINDRES@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +libdir = @libdir@ +plugindir ?= ${libdir}/${PACKAGE_NAME} +datarootdir = @datarootdir@ +datadir = @datadir@ +includedir = @includedir@ +includesubdir ?= ${PACKAGE_NAME} +localedir = @localedir@ +localename ?= ${PACKAGE_NAME} +mandir = @mandir@ +mansubdir ?= man1 + +OBJS1 = ${SRCS:.c=.o} +OBJS2 = ${OBJS1:.cc=.o} +OBJS3 = ${OBJS2:.cxx=.o} +OBJS4 = ${OBJS3:.d=.o} +OBJS5 = ${OBJS4:.erl=.beam} +OBJS6 = ${OBJS5:.java=.class} +OBJS7 = ${OBJS6:.m=.o} +OBJS8 = ${OBJS7:.mm=.o} +OBJS9 = ${OBJS8:.py=.pyc} +OBJS10 = ${OBJS9:.rc=.o} +OBJS11 = ${OBJS10:.S=.o} +OBJS += ${OBJS11:.xpm=.o} + +LIB_OBJS = ${OBJS:.o=.lib.o} +MORPHOS_LIB_OBJS = ${OBJS:.o=.moslib.o} +PLUGIN_OBJS = ${OBJS:.o=.plugin.o} + +MO_FILES = ${LOCALES:.po=.mo} + +.SILENT: +.SUFFIXES: +.SUFFIXES: .beam .c .c.dep .cc .cc.dep .class .cxx .cxx.dep .d .erl .lib.o .java .mo .m .m.dep .mm .mm.dep .moslib.o .o .plugin.o .po .py .pyc .rc .S .S.dep .xpm +.PHONY: all subdirs subdirs-after pre-depend depend install install-includes install-extra uninstall uninstall-extra clean distclean locales ${SUBDIRS} ${SUBDIRS_AFTER} + +all: + ${MAKE} pre-all + ${MAKE} subdirs + ${MAKE} depend + ${MAKE} ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${MORPHOS_LIB} ${MORPHOS_LIB_NOINST} ${PLUGIN} ${PLUGIN_NOINST} ${PROG} ${PROG_NOINST} ${JARFILE} locales + ${MAKE} subdirs-after + ${MAKE} post-all + +pre-all post-all: + +subdirs: ${SUBDIRS} +subdirs-after: ${SUBDIRS_AFTER} + +${SUBDIRS} ${SUBDIRS_AFTER}: + for i in $@; do \ + ${DIR_ENTER}; \ + ${MAKE} || exit $$?; \ + ${DIR_LEAVE}; \ + done + +depend: pre-depend ${SRCS} + regen=0; \ + deps=""; \ + test -f .deps || regen=1; \ + for i in "" ${SRCS}; do \ + case $$i in \ + "") \ + ;; \ + *.c) \ + if test x"${CC_DEPENDS}" = x"yes"; then \ + test $$i -nt .deps && regen=1; \ + deps="$$deps $$i.dep"; \ + fi; \ + ;; \ + *.cc | *.cxx) \ + if test x"${CXX_DEPENDS}" = x"yes"; then \ + test $$i -nt .deps && regen=1; \ + deps="$$deps $$i.dep"; \ + fi; \ + ;; \ + *.m) \ + if test x"${OBJC_DEPENDS}" = x"yes"; then \ + test $$i -nt .deps && regen=1; \ + deps="$$deps $$i.dep"; \ + fi; \ + ;; \ + *.mm) \ + if test x"${OBJCXX_DEPENDS}" = x"yes"; then \ + test $$i -nt .deps && regen=1; \ + deps="$$deps $$i.dep"; \ + fi; \ + ;; \ + *.S) \ + if test x"${AS_DEPENDS}" = x"yes"; then \ + test $$i -nt .deps && regen=1; \ + deps="$$deps $$i.dep"; \ + fi; \ + ;; \ + esac; \ + done; \ + if test x"$$regen" = x"1" -a x"$$deps" != x""; then \ + ${DEPEND_STATUS}; \ + if ${MAKE} $$deps && cat $$deps >.deps; then \ + rm -f $$deps; \ + ${DEPEND_OK}; \ + else \ + :> .deps; \ + touch -t 0001010000 .deps; \ + ${DEPEND_FAILED}; \ + fi; \ + fi + +.c.c.dep: + ${CPP} ${CPPFLAGS} ${CFLAGS} -M $< | \ + sed 's/^\([^\.]*\)\.o:/\1.o \1.lib.o \1.moslib.o \1.plugin.o:/' >$@ || \ + { rm -f $@; false; } + +.cc.cc.dep .cxx.cxx.dep: + ${CPP} ${CPPFLAGS} ${CXXFLAGS} -M $< | \ + sed 's/^\([^\.]*\)\.o:/\1.o \1.lib.o \1.moslib.o \1.plugin.o:/' >$@ || \ + { rm -f $@; false; } + +.m.m.dep: + ${CPP} ${CPPFLAGS} ${OBJCFLAGS} -M $< | \ + sed 's/^\([^\.]*\)\.o:/\1.o \1.lib.o \1.moslib.o \1.plugin.o:/' >$@ || \ + { rm -f $@; false; } + +.mm.mm.dep: + ${CPP} ${CPPFLAGS} ${OBJCPPFLAGS} -M $< | \ + sed 's/^\([^\.]*\)\.o:/\1.o \1.lib.o \1.moslib.o \1.plugin.o:/' >$@ || \ + { rm -f $@; false; } + +.S.S.dep: + ${CPP} ${CPPFLAGS} ${ASFLAGS} -M $< | \ + sed 's/^\([^\.]*\)\.o:/\1.o \1.lib.o \1.moslib.o \1.plugin.o:/' >$@ || \ + { rm -f $@; false; } + +pre-depend: + +${PROG} ${PROG_NOINST}: ${EXT_DEPS} ${OBJS} ${OBJS_EXTRA} + ${LINK_STATUS} + out="$@"; \ + if ${LD} -o $@ ${OBJS} ${OBJS_EXTRA} ${LDFLAGS} ${LIBS}; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + fi + +${JARFILE}: ${EXT_DEPS} ${JAR_MANIFEST} ${OBJS} ${OBJS_EXTRA} + ${LINK_STATUS} + if test x"${JAR_MANIFEST}" != x""; then \ + if ${JAR} cfm ${JARFILE} ${JAR_MANIFEST} ${OBJS} ${OBJS_EXTRA}; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + fi \ + else \ + if ${JAR} cf ${JARFILE} ${OBJS} ${OBJS_EXTRA}; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + fi \ + fi + +${SHARED_LIB} ${SHARED_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA} + ${LINK_STATUS} + out="$@"; \ + if ${LD} -o $@ ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LIB_LDFLAGS} ${LIB_LDFLAGS_INSTALL_NAME} ${LDFLAGS} ${LIBS}; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + fi + +${FRAMEWORK}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA} + rm -fr $@ + ${MKDIR_P} $@ + ${MAKE} INSTALL_INCLUDES_IF_SUBDIR=${includesubdir} INSTALL_INCLUDES_DESTINATION=$$PWD/$@/Headers install-includes + if test -f Info.plist; then \ + i=Info.plist; \ + ${INSTALL_STATUS}; \ + if ${INSTALL} -m 644 $$i $@/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + fi + if test -f module.modulemap; then \ + i=module.modulemap; \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} $@/Modules && ${INSTALL} -m 644 $$i $@/Modules/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + fi + ${LINK_STATUS} + out="$@"; \ + if ${LD} -o $$out/$${out%.framework} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${FRAMEWORK_LDFLAGS} ${FRAMEWORK_LDFLAGS_INSTALL_NAME} ${LDFLAGS} ${LIBS} && ${CODESIGN} -fs ${CODESIGN_IDENTITY} --timestamp=none $$out; then \ + ${LINK_OK}; \ + else \ + rm -fr $$out; \ + ${LINK_FAILED}; \ + fi + +${MORPHOS_LIB} ${MORPHOS_LIB_NOINST}: ${EXT_DEPS} ${MORPHOS_LIB_OBJS} ${MORPHOS_LIB_OBJS_EXTRA} + ${LINK_STATUS} + if ${LD} -o $@ ${MORPHOS_LIB_OBJS} ${MORPHOS_LIB_OBJS_EXTRA} -nostartfiles ${LDFLAGS} ${LIBS}; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + fi + +${PLUGIN} ${PLUGIN_NOINST}: ${EXT_DEPS} ${PLUGIN_OBJS} + ${LINK_STATUS} + out="$@"; \ + if ${LD} -o $@ ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + fi + +${STATIC_LIB} ${STATIC_LIB_NOINST}: ${EXT_DEPS} ${OBJS} ${OBJS_EXTRA} + ${LINK_STATUS} + rm -f $@ + out="$@"; \ + objs=""; \ + ars=""; \ + for i in ${OBJS} ${OBJS_EXTRA}; do \ + case $$i in \ + *.a) \ + ars="$$ars $$i" \ + ;; \ + *.o) \ + objs="$$objs $$i" \ + ;; \ + esac \ + done; \ + for i in $$ars; do \ + dir=".$$(echo $$i | sed 's/\//_/g').objs"; \ + rm -fr $$dir; \ + mkdir -p $$dir; \ + cd $$dir; \ + ${AR} x ../$$i; \ + for j in *.o; do \ + objs="$$objs $$dir/$$j"; \ + done; \ + cd ..; \ + done; \ + if ${AR} cr $@ $$objs && ${RANLIB} $@; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + rm -f $@; \ + fi; \ + for i in $$ars; do \ + dir=".$$(echo $$i | sed 's/\//_/g').objs"; \ + rm -fr $$dir; \ + done + +${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA} + ${LINK_STATUS} + rm -f $@ + out="$@"; \ + objs=""; \ + ars=""; \ + for i in ${LIB_OBJS} ${LIB_OBJS_EXTRA}; do \ + case $$i in \ + *.a) \ + ars="$$ars $$i" \ + ;; \ + *.o) \ + objs="$$objs $$i" \ + ;; \ + esac \ + done; \ + for i in $$ars; do \ + dir=".$$(echo $$i | sed 's/\//_/g').objs"; \ + rm -fr $$dir; \ + mkdir -p $$dir; \ + cd $$dir; \ + ${AR} x ../$$i; \ + for j in *.o; do \ + objs="$$objs $$dir/$$j"; \ + done; \ + cd ..; \ + done; \ + if ${AR} cr $@ $$objs && ${RANLIB} $@; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + rm -f $@; \ + fi; \ + for i in $$ars; do \ + dir=".$$(echo $$i | sed 's/\//_/g').objs"; \ + rm -fr $$dir; \ + done + +locales: ${MO_FILES} + +.c.o: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if ${CC} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi +.c.lib.o: + ${COMPILE_LIB_STATUS} + in="$<"; \ + out="$@"; \ + if ${CC} ${LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_LIB_OK}; \ + else \ + ${COMPILE_LIB_FAILED}; \ + fi +.c.moslib.o: + ${COMPILE_MOSLIB_STATUS} + in="$<"; \ + out="$@"; \ + if ${CC} -mbaserel32 ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_MOSLIB_OK}; \ + else \ + ${COMPILE_MOSLIB_FAILED}; \ + fi +.c.plugin.o: + ${COMPILE_PLUGIN_STATUS} + in="$<"; \ + out="$@"; \ + if ${CC} ${PLUGIN_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_PLUGIN_OK}; \ + else \ + ${COMPILE_PLUGIN_FAILED}; \ + fi + +.cc.o .cxx.o: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if ${CXX} ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} ${CXXFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi +.cc.lib.o .cxx.lib.o: + ${COMPILE_LIB_STATUS} + in="$<"; \ + out="$@"; \ + if ${CXX} ${LIB_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} ${CXXFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_LIB_OK}; \ + else \ + ${COMPILE_LIB_FAILED}; \ + fi +.cc.moslib.o .cxx.moslib.o: + ${COMPILE_MOSLIB_STATUS} + in="$<"; \ + out="$@"; \ + if ${CXX} -mbaserel32 ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} ${CXXFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_MOSLIB_OK}; \ + else \ + ${COMPILE_MOSLIB_FAILED}; \ + fi +.cc.plugin.o .cxx.plugin.o: + ${COMPILE_PLUGIN_STATUS} + in="$<"; \ + out="$@"; \ + if ${CXX} ${PLUGIN_CFLAGS} ${CXXFLAGS} ${CPPFLAGS} ${CXXFLAGS_$<} ${CXXFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_PLUGIN_OK}; \ + else \ + ${COMPILE_PLUGIN_FAILED}; \ + fi + +.d.o: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if test x"$(basename ${DC})" = x"dmd"; then \ + if ${DC} ${DFLAGS} -c -of$@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi \ + else \ + if ${DC} ${DFLAGS} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi \ + fi + +.erl.beam: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if ${ERLC} ${ERLCFLAGS} -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.java.class: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if ${JAVAC} ${JAVACFLAGS} $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.m.o: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if ${OBJC} ${OBJCFLAGS} ${CPPFLAGS} ${OBJCFLAGS_$<} ${OBJCFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi +.m.lib.o: + ${COMPILE_LIB_STATUS} + in="$<"; \ + out="$@"; \ + if ${OBJC} ${LIB_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} ${OBJCFLAGS_$<} ${OBJCFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_LIB_OK}; \ + else \ + ${COMPILE_LIB_FAILED}; \ + fi +.m.moslib.o: + ${COMPILE_MOSLIB_STATUS} + in="$<"; \ + out="$@"; \ + if ${OBJC} -mbaserel32 ${OBJCFLAGS} ${CPPFLAGS} ${OBJCFLAGS_$<} ${OBJCFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_MOSLIB_OK}; \ + else \ + ${COMPILE_MOSLIB_FAILED}; \ + fi +.m.plugin.o: + ${COMPILE_PLUGIN_STATUS} + in="$<"; \ + out="$@"; \ + if ${OBJC} ${PLUGIN_CFLAGS} ${OBJCFLAGS} ${CPPFLAGS} ${OBJCFLAGS_$<} ${OBJCFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_PLUGIN_OK}; \ + else \ + ${COMPILE_PLUGIN_FAILED}; \ + fi + +.mm.o: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if ${OBJCXX} ${OBJCXXFLAGS} ${CPPFLAGS} ${OBJCXXFLAGS_$<} ${OBJCXXFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi +.mm.lib.o: + ${COMPILE_LIB_STATUS} + in="$<"; \ + out="$@"; \ + if ${OBJCXX} ${LIB_CFLAGS} ${OBJCXXFLAGS} ${CPPFLAGS} ${OBJCXXFLAGS_$<} ${OBJCXXFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_LIB_OK}; \ + else \ + ${COMPILE_LIB_FAILED}; \ + fi +.mm.moslib.o: + ${COMPILE_MOSLIB_STATUS} + in="$<"; \ + out="$@"; \ + if ${OBJCXX} -mbaserel32 ${OBJCXXFLAGS} ${CPPFLAGS} ${OBJCXXFLAGS_$<} ${OBJCXXFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_MOSLIB_OK}; \ + else \ + ${COMPILE_MOSLIB_FAILED}; \ + fi +.mm.plugin.o: + ${COMPILE_PLUGIN_STATUS} + in="$<"; \ + out="$@"; \ + if ${OBJCXX} ${PLUGIN_CFLAGS} ${OBJCXXFLAGS} ${CPPFLAGS} ${OBJCXXFLAGS_$<} ${OBJCXXFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_PLUGIN_OK}; \ + else \ + ${COMPILE_PLUGIN_FAILED}; \ + fi + +.po.mo: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if ${MSGFMT} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.py.pyc: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if ${PYTHON} ${PYTHON_FLAGS} -c "import py_compile; py_compile.compile('$<')"; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.rc.o .rc.lib.o .rc.plugin.o: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if ${WINDRES} -J rc -O coff -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.S.o .S.moslib.o: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if ${AS} ${ASFLAGS} ${CPPFLAGS} ${ASFLAGS_$<} ${ASFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi +.S.lib.o: + ${COMPILE_LIB_STATUS} + in="$<"; \ + out="$@"; \ + if ${AS} ${LIB_CFLAGS} ${ASFLAGS} ${CPPFLAGS} ${ASFLAGS_$<} ${ASFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_LIB_OK}; \ + else \ + ${COMPILE_LIB_FAILED}; \ + fi +.S.plugin.o: + ${COMPILE_PLUGIN_STATUS} + in="$<"; \ + out="$@"; \ + if ${AS} ${PLUGIN_CFLAGS} ${ASFLAGS} ${CPPFLAGS} ${ASFLAGS_$<} ${ASFLAGS_$@} -c -o $@ $<; then \ + ${COMPILE_PLUGIN_OK}; \ + else \ + ${COMPILE_PLUGIN_FAILED}; \ + fi + +.xpm.o: + ${COMPILE_STATUS} + in="$<"; \ + out="$@"; \ + if ${CC} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -x c -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi +.xpm.lib.o: + ${COMPILE_LIB_STATUS} + in="$<"; \ + out="$@"; \ + if ${CC} ${LIB_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -x c -c -o $@ $<; then \ + ${COMPILE_LIB_OK}; \ + else \ + ${COMPILE_LIB_FAILED}; \ + fi +.xpm.moslib.o: + ${COMPILE_MOSLIB_STATUS} + in="$<"; \ + out="$@"; \ + if ${CC} -mbasel32 ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -x c -c -o $@ $<; then \ + ${COMPILE_MOSLIB_OK}; \ + else \ + ${COMPILE_MOSLIB_FAILED}; \ + fi +.xpm.plugin.o: + ${COMPILE_PLUGIN_STATUS} + in="$<"; \ + out="$@"; \ + if ${CC} ${PLUGIN_CFLAGS} ${CFLAGS} ${CPPFLAGS} ${CFLAGS_$<} ${CFLAGS_$@} -x c -c -o $@ $<; then \ + ${COMPILE_PLUGIN_OK}; \ + else \ + ${COMPILE_PLUGIN_FAILED}; \ + fi + +install: install-extra + for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ + test x"$$i" = x"" && continue; \ + ${DIR_ENTER}; \ + ${MAKE} install || exit $$?; \ + ${DIR_LEAVE}; \ + done + + for i in "" ${SHARED_LIB}; do \ + test x"$$i" = x"" && continue; \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${libdir} ${INSTALL_LIB}; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in "" ${STATIC_LIB} ${STATIC_PIC_LIB}; do \ + test x"$$i" = x"" && continue; \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${libdir} && ${INSTALL} -m 644 $$i ${DESTDIR}${libdir}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in "" ${PLUGIN}; do \ + test x"$$i" = x"" && continue; \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${plugindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in "" ${DATA}; do \ + test x"$$i" = x"" && continue; \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} $$(dirname ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i) && ${INSTALL} -m 644 $$i ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in "" ${PROG}; do \ + test x"$$i" = x"" && continue; \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in "" ${INCLUDES}; do \ + test x"$$i" = x"" && continue; \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${includedir}/${includesubdir} && ${INSTALL} -m 644 $$i ${DESTDIR}${includedir}/${includesubdir}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in "" ${MO_FILES}; do \ + test x"$$i" = x"" && continue; \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${localedir}/$${i%.mo}/LC_MESSAGES && ${INSTALL} -m 644 $$i ${DESTDIR}${localedir}/$${i%.mo}/LC_MESSAGES/${localename}.mo; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in "" ${MAN}; do \ + test x"$$i" = x"" && continue; \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${mandir}/${mansubdir} && ${INSTALL} -m 644 $$i ${DESTDIR}${mandir}/${mansubdir}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + +install-includes: + for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ + test x"$$i" = x"" && continue; \ + ${DIR_ENTER}; \ + ${MAKE} install-includes || exit $$?; \ + ${DIR_LEAVE}; \ + done + + if test x"${INSTALL_INCLUDES_IF_SUBDIR}" = x"" -o x"${includesubdir}" = x"${INSTALL_INCLUDES_IF_SUBDIR}"; then \ + if test x"${INSTALL_INCLUDES_DESTINATION}" != x""; then \ + destination="${INSTALL_INCLUDES_DESTINATION}"; \ + else \ + destination="${DESTDIR}${includedir}/${includesubdir}"; \ + fi; \ + \ + for i in "" ${INCLUDES}; do \ + test x"$$i" = x"" && continue; \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} $$destination && ${INSTALL} -m 644 $$i $$destination/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done; \ + fi + +install-extra: + +uninstall: uninstall-extra + for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ + test x"$$i" = x"" && continue; \ + ${DIR_ENTER}; \ + ${MAKE} uninstall || exit $$?; \ + ${DIR_LEAVE}; \ + done + + for i in "" ${SHARED_LIB}; do \ + test x"$$i" = x"" && continue; \ + if test -f ${DESTDIR}${libdir}/$$i; then \ + if : ${UNINSTALL_LIB}; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi; \ + done + + for i in "" ${STATIC_LIB} ${STATIC_PIC_LIB}; do \ + test x"$$i" = x"" && continue; \ + if test -f ${DESTDIR}${libdir}/$$i; then \ + if rm -f ${DESTDIR}${libdir}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + + for i in "" ${PLUGIN}; do \ + test x"$$i" = x"" && continue; \ + if test -f ${DESTDIR}${plugindir}/$$i; then \ + if rm -f ${DESTDIR}${plugindir}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + -rmdir ${DESTDIR}${plugindir} >/dev/null 2>&1 + + for i in "" ${DATA}; do \ + test x"$$i" = x"" && continue; \ + if test -f ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i; then \ + if rm -f ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi; \ + rmdir "$$(dirname ${DESTDIR}${datadir}/${PACKAGE_NAME}/$$i)" >/dev/null 2>&1 || true; \ + done + -rmdir ${DESTDIR}${datadir}/${PACKAGE_NAME} >/dev/null 2>&1 + + for i in "" ${PROG}; do \ + test x"$$i" = x"" && continue; \ + if test -f ${DESTDIR}${bindir}/$$i; then \ + if rm -f ${DESTDIR}${bindir}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + + for i in "" ${INCLUDES}; do \ + test x"$$i" = x"" && continue; \ + if test -f ${DESTDIR}${includedir}/${includesubdir}/$$i; then \ + if rm -f ${DESTDIR}${includedir}/${includesubdir}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + -rmdir ${DESTDIR}${includedir}/${includesubdir} >/dev/null 2>&1 + + for i in "" ${MO_FILES}; do \ + test x"$$i" = x"" && continue; \ + if test -f ${DESTDIR}${localedir}/$${i%.mo}/LC_MESSAGES/${localename}.mo; then \ + if rm -f ${DESTDIR}${localedir}/$${i%.mo}/LC_MESSAGES/${localename}.mo; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + + for i in "" ${MAN}; do \ + test x"$$i" = x"" && continue; \ + if test -f ${DESTDIR}${mandir}/${mansubdir}/$$i; then \ + if rm -f ${DESTDIR}${mandir}/${mansubdir}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + +uninstall-extra: + +clean: + for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ + test x"$$i" = x"" && continue; \ + ${DIR_ENTER}; \ + ${MAKE} clean || exit $$?; \ + ${DIR_LEAVE}; \ + done + + for i in "" ${DEPS} ${OBJS} ${OBJS_EXTRA} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${MORPHOS_LIB_OBJS} ${MORPHOS_LIB_OBJS_EXTRA} ${PLUGIN_OBJS} ${PROG} ${PROG_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${FRAMEWORK} ${PLUGIN} ${PLUGIN_NOINST} ${CLEAN_LIB} ${MO_FILES} ${CLEAN}; do \ + test x"$$i" = x"" && continue; \ + if test -f $$i -o -d $$i; then \ + if rm -fr $$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + +distclean: clean + for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ + test x"$$i" = x"" && continue; \ + ${DIR_ENTER}; \ + ${MAKE} distclean || exit $$?; \ + ${DIR_LEAVE}; \ + done + + for i in "" ${DISTCLEAN} .deps *~; do \ + test x"$$i" = x"" && continue; \ + if test -f $$i -o -d $$i; then \ + if rm -fr $$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + +print-hierarchy: + for i in "" ${SUBDIRS} ${SUBDIRS_AFTER}; do \ + test x"$$i" = x"" && continue; \ + echo ${PRINT_HIERARCHY_PREFIX}$$i; \ + cd $$i || exit $$?; \ + ${MAKE} PRINT_HIERARCHY_PREFIX=$$i/ print-hierarchy || exit $$?; \ + cd .. || exit $$?; \ + done + +print-var: + printf '%s\n' '${${VAR}}' + +DIR_ENTER = printf "@TERM_EL@@TERM_SETAF6@Entering directory @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF6@.@TERM_SGR0@\n" "$$i"; cd $$i || exit $$? +DIR_LEAVE = printf "@TERM_EL@@TERM_SETAF6@Leaving directory @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF6@.@TERM_SGR0@\n" "$$i"; cd .. || exit $$? +DEPEND_STATUS = printf "@TERM_EL@@TERM_SETAF3@Generating dependencies...@TERM_SGR0@\r" +DEPEND_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully generated dependencies.@TERM_SGR0@\n" +DEPEND_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to generate dependencies!@TERM_SGR0@\n"; exit $$err +COMPILE_STATUS = printf "@TERM_EL@@TERM_SETAF3@Compiling @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF3@...@TERM_SGR0@\r" "$<" +COMPILE_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully compiled @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF2@.@TERM_SGR0@\n" "$<" +COMPILE_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to compile @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF1@!@TERM_SGR0@\n" "$<"; exit $$err +COMPILE_LIB_STATUS = printf "@TERM_EL@@TERM_SETAF3@Compiling @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF3@ (lib)...@TERM_SGR0@\r" "$<" +COMPILE_LIB_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully compiled @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF2@ (lib).@TERM_SGR0@\n" "$<" +COMPILE_LIB_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to compile @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF1@ (lib)!@TERM_SGR0@\n" "$<"; exit $$err +COMPILE_MOSLIB_STATUS = printf "@TERM_EL@@TERM_SETAF3@Compiling @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF3@ (moslib)...@TERM_SGR0@\r" "$<" +COMPILE_MOSLIB_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully compiled @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF2@ (moslib).@TERM_SGR0@\n" "$<" +COMPILE_MOSLIB_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to compile @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF1@ (moslib)!@TERM_SGR0@\n" "$<"; exit $$err +COMPILE_PLUGIN_STATUS = printf "@TERM_EL@@TERM_SETAF3@Compiling @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF3@ (plugin)...@TERM_SGR0@\r" "$<" +COMPILE_PLUGIN_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully compiled @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF2@ (plugin).@TERM_SGR0@\n" "$<" +COMPILE_PLUGIN_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to compile @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF1@ (plugin)!@TERM_SGR0@\n" "$<"; exit $$err +LINK_STATUS = printf "@TERM_EL@@TERM_SETAF3@Linking @TERM_BOLD@$@@TERM_SGR0@@TERM_SETAF3@...@TERM_SGR0@\r" +LINK_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully linked @TERM_BOLD@$@@TERM_SGR0@@TERM_SETAF2@.@TERM_SGR0@\n" +LINK_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to link @TERM_BOLD@$@@TERM_SGR0@@TERM_SETAF1@!@TERM_SGR0@\n"; exit $$err +INSTALL_STATUS = printf "@TERM_EL@@TERM_SETAF3@Installing @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF3@...@TERM_SGR0@\r" "$$i" +INSTALL_OK = printf "@TERM_EL@@TERM_SETAF2@Successfully installed @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF2@.@TERM_SGR0@\n" "$$i" +INSTALL_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to install @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF1@!@TERM_SGR0@\n" "$$i"; exit $$err +DELETE_OK = printf "@TERM_EL@@TERM_SETAF4@Deleted @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF4@.@TERM_SGR0@\n" "$$i" +DELETE_FAILED = err=$$?; printf "@TERM_EL@@TERM_SETAF1@Failed to delete @TERM_BOLD@%s@TERM_SGR0@@TERM_SETAF1@!@TERM_SGR0@\n" "$$i"; exit $$err + +.CURDIR ?= . +-include ${.CURDIR}/.deps diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..2221e6a --- /dev/null +++ b/config.h.in @@ -0,0 +1,142 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Build stamp */ +#undef BUILDSTAMP + +/* Copyright */ +#undef COPYRIGHT + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Define to compiler syntax for public symbols */ +#undef EXPORT + +/* target GLib 2.32 */ +#undef GLIB_VERSION_MIN_REQUIRED + +/* Define to 1 if you have the Mac OS X function + CFLocaleCopyPreferredLanguages in the CoreFoundation framework. */ +#undef HAVE_CFLOCALECOPYPREFERREDLANGUAGES + +/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in + the CoreFoundation framework. */ +#undef HAVE_CFPREFERENCESCOPYAPPVALUE + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +#undef HAVE_DCGETTEXT + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#undef HAVE_GETTEXT + +/* Define if you have the iconv() function and it works. */ +#undef HAVE_ICONV + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `sigwait' function. */ +#undef HAVE_SIGWAIT + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define as const if the declaration of iconv() needs const. */ +#undef ICONV_CONST + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Suffix for plugins */ +#undef PLUGIN_SUFFIX + +/* Qt 6 is not supported yet */ +#undef QT_NO_DEPRECATED_WARNINGS + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if D-Bus support enabled */ +#undef USE_DBUS + +/* Define if GTK+ support enabled */ +#undef USE_GTK + +/* Define if Qt support enabled */ +#undef USE_QT + +/* Define to allow Valgrind analysis */ +#undef VALGRIND_FRIENDLY + +/* Version number of package */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* "Use GNU-style printf" */ +#undef __USE_MINGW_ANSI_STDIO diff --git a/configure b/configure new file mode 100755 index 0000000..2f13e59 --- /dev/null +++ b/configure @@ -0,0 +1,11888 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for audacious 4.0.5. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +# +# Copyright (C) 2001-2020 Audacious developers and others +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='audacious' +PACKAGE_TARNAME='audacious' +PACKAGE_VERSION='4.0.5' +PACKAGE_STRING='audacious 4.0.5' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +gt_needs= +ac_subst_vars='TERM_SETAF6 +TERM_SETAF4 +TERM_SETAF3 +TERM_SETAF2 +TERM_SETAF1 +TERM_BOLD +TERM_SGR0 +TERM_EL +TPUT +OBJCXX_DEPENDS +OBJC_DEPENDS +CXX_DEPENDS +CC_DEPENDS +LTLIBOBJS +LIBOBJS +GENERATED_FILES +plugindir +VALGRIND_FRIENDLY +USE_DBUS +have_dbus +BUILDSTAMP +POSUB +LTLIBINTL +LIBINTL +INTLLIBS +INTL_MACOSX_LIBS +XGETTEXT_EXTRA_OPTIONS +MSGMERGE_FOR_MSGFMT_OPTION +MSGMERGE +XGETTEXT_015 +XGETTEXT +GMSGFMT_015 +GMSGFMT +MSGFMT +GETTEXT_MACRO_VERSION +USE_NLS +SED +MKDIR_P +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +SET_MAKE +LTLIBICONV +LIBICONV +pkgconfigdir +CLEAN_LIB +UNINSTALL_LIB +INSTALL_LIB +PLUGIN_SUFFIX +PLUGIN_LDFLAGS +PLUGIN_CFLAGS +LDFLAGS_RPATH +LIB_SUFFIX +LIB_PREFIX +LIB_LDFLAGS_INSTALL_NAME +LIB_LDFLAGS +LIB_CFLAGS +USE_QT +QT_LIBS +QT_CFLAGS +QTBINPATH +QTCORE_LIBS +QTCORE_CFLAGS +GIO_LIBS +GIO_CFLAGS +USE_GTK +GTK_LIBS +GTK_CFLAGS +GMODULE_LIBS +GMODULE_CFLAGS +GLIB_LIBS +GLIB_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +WINDRES +RANLIB +AR +CP +MV +RM +LN_S +BIGENDIAN +OBJCXXCPP +ac_ct_OBJCXX +OBJCXXFLAGS +OBJCXX +OBJCPP +ac_ct_OBJC +OBJCFLAGS +OBJC +EGREP +GREP +CPP +ac_ct_CXX +CXXFLAGS +CXX +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +HAVE_DARWIN +HAVE_LINUX +HAVE_MSWINDOWS +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +COPYRIGHT +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_largefile +enable_gtk +enable_qt +with_pkgconfigdir +with_gnu_ld +enable_rpath +with_libiconv_prefix +enable_nls +with_libintl_prefix +with_buildstamp +enable_dbus +enable_valgrind +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP +OBJC +OBJCFLAGS +OBJCPP +OBJCXX +OBJCXXFLAGS +OBJCXXCPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +GLIB_CFLAGS +GLIB_LIBS +GMODULE_CFLAGS +GMODULE_LIBS +GTK_CFLAGS +GTK_LIBS +GIO_CFLAGS +GIO_LIBS +QTCORE_CFLAGS +QTCORE_LIBS +QTBINPATH +QT_CFLAGS +QT_LIBS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures audacious 4.0.5 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/audacious] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of audacious 4.0.5:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-largefile omit support for large files + --enable-gtk Enable GTK+ support (default=disabled) + --disable-qt Disable Qt support (default=enabled) + --disable-rpath do not hardcode runtime library paths + --disable-nls do not use Native Language Support + --disable-dbus Disable D-Bus support (default=enabled) + --enable-valgrind Valgrind analysis support (default=disabled) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pkgconfigdir pkg-config installation directory + ['${libdir}/pkgconfig'] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib + --without-libiconv-prefix don't search for libiconv in includedir and libdir + --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib + --without-libintl-prefix don't search for libintl in includedir and libdir + --with-buildstamp=XXX Set build stamp to XXX + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + OBJC Objective C compiler command + OBJCFLAGS Objective C compiler flags + OBJCPP Objective C preprocessor + OBJCXX Objective C++ compiler command + OBJCXXFLAGS Objective C++ compiler flags + OBJCXXCPP Objective C++ preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + GLIB_CFLAGS C compiler flags for GLIB, overriding pkg-config + GLIB_LIBS linker flags for GLIB, overriding pkg-config + GMODULE_CFLAGS + C compiler flags for GMODULE, overriding pkg-config + GMODULE_LIBS + linker flags for GMODULE, overriding pkg-config + GTK_CFLAGS C compiler flags for GTK, overriding pkg-config + GTK_LIBS linker flags for GTK, overriding pkg-config + GIO_CFLAGS C compiler flags for GIO, overriding pkg-config + GIO_LIBS linker flags for GIO, overriding pkg-config + QTCORE_CFLAGS + C compiler flags for QTCORE, overriding pkg-config + QTCORE_LIBS linker flags for QTCORE, overriding pkg-config + QTBINPATH value of host_bins for Qt5Core >= 5.2, overriding pkg-config + QT_CFLAGS C compiler flags for QT, overriding pkg-config + QT_LIBS linker flags for QT, overriding pkg-config + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +audacious configure 4.0.5 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. + +Copyright (C) 2001-2020 Audacious developers and others +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_objc_try_compile LINENO +# ----------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_objc_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_objc_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_objc_try_compile + +# ac_fn_objc_try_cpp LINENO +# ------------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_objc_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_objc_preproc_warn_flag$ac_objc_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_objc_try_cpp + +# ac_fn_objcxx_try_compile LINENO +# ------------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_objcxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_objcxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_objcxx_try_compile + +# ac_fn_objcxx_try_cpp LINENO +# --------------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_objcxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_objcxx_preproc_warn_flag$ac_objcxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_objcxx_try_cpp + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by audacious $as_me 4.0.5, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +gt_needs="$gt_needs " +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$PACKAGE_VERSION" +_ACEOF + + +COPYRIGHT="Copyright (C) 2001-2020 Audacious developers and others" + +cat >>confdefs.h <<_ACEOF +#define COPYRIGHT "$COPYRIGHT" +_ACEOF + + + +ac_aux_dir= +for ac_dir in build-aux "$srcdir"/build-aux; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +ac_config_headers="$ac_config_headers config.h" + + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if ${ac_cv_target+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi + + +fi + + + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking operating system type" >&5 +$as_echo_n "checking operating system type... " >&6; } + +HAVE_LINUX=no +HAVE_MSWINDOWS=no +HAVE_DARWIN=no + +case "$target" in + *linux*) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Linux" >&5 +$as_echo "Linux" >&6; } + HAVE_LINUX=yes + ;; + *mingw*) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Windows" >&5 +$as_echo "Windows" >&6; } + HAVE_MSWINDOWS=yes + ;; + *darwin*) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Darwin" >&5 +$as_echo "Darwin" >&6; } + HAVE_DARWIN=yes + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: other UNIX" >&5 +$as_echo "other UNIX" >&6; } + ;; +esac + + + + + + + + + + +if test "x$GCC" = "xyes"; then + CFLAGS="$CFLAGS -std=gnu99 -ffast-math -Wall -pipe" + if test "x$HAVE_DARWIN" = "xyes"; then + CXXFLAGS="$CXXFLAGS -std=gnu++11 -ffast-math -Wall -pipe" + LDFLAGS="$LDFLAGS" + else + CXXFLAGS="$CXXFLAGS -std=gnu++11 -ffast-math -Wall -pipe" + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C/C++ compiler supports -Wtype-limits" >&5 +$as_echo_n "checking whether the C/C++ compiler supports -Wtype-limits... " >&6; } + OLDCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wtype-limits -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$OLDCFLAGS -Wtype-limits" + CXXFLAGS="$CXXFLAGS -Wtype-limits" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$OLDCFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C/C++ compiler supports -Wno-stringop-truncation" >&5 +$as_echo_n "checking whether the C/C++ compiler supports -Wno-stringop-truncation... " >&6; } + OLDCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wno-stringop-truncation -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$OLDCFLAGS -Wno-stringop-truncation" + CXXFLAGS="$CXXFLAGS -Wno-stringop-truncation" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$OLDCFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler supports -Woverloaded-virtual" >&5 +$as_echo_n "checking whether the C++ compiler supports -Woverloaded-virtual... " >&6; } + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + OLDCXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -Woverloaded-virtual -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CXXFLAGS="$OLDCXXFLAGS -Woverloaded-virtual" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CXXFLAGS="$OLDCXXFLAGS" + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +fi + + +if test "x$HAVE_DARWIN" = "xyes"; then + ac_ext=m +ac_cpp='$OBJCPP $CPPFLAGS' +ac_compile='$OBJC -c $OBJCFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$OBJC -o conftest$ac_exeext $OBJCFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_objc_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in gcc objcc objc cc CC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJC"; then + ac_cv_prog_OBJC="$OBJC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJC=$ac_cv_prog_OBJC +if test -n "$OBJC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJC" >&5 +$as_echo "$OBJC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$OBJC" && break + done +fi +if test -z "$OBJC"; then + ac_ct_OBJC=$OBJC + for ac_prog in gcc objcc objc cc CC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJC"; then + ac_cv_prog_ac_ct_OBJC="$ac_ct_OBJC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJC=$ac_cv_prog_ac_ct_OBJC +if test -n "$ac_ct_OBJC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJC" >&5 +$as_echo "$ac_ct_OBJC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_OBJC" && break +done + + if test "x$ac_ct_OBJC" = x; then + OBJC="gcc" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJC=$ac_ct_OBJC + fi +fi + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for Objective C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5 +$as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; } +if ${ac_cv_objc_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_objc_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_objc_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objc_compiler_gnu" >&5 +$as_echo "$ac_cv_objc_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GOBJC=yes +else + GOBJC= +fi +ac_test_OBJCFLAGS=${OBJCFLAGS+set} +ac_save_OBJCFLAGS=$OBJCFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5 +$as_echo_n "checking whether $OBJC accepts -g... " >&6; } +if ${ac_cv_prog_objc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_objc_werror_flag=$ac_objc_werror_flag + ac_objc_werror_flag=yes + ac_cv_prog_objc_g=no + OBJCFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_objc_try_compile "$LINENO"; then : + ac_cv_prog_objc_g=yes +else + OBJCFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_objc_try_compile "$LINENO"; then : + +else + ac_objc_werror_flag=$ac_save_objc_werror_flag + OBJCFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_objc_try_compile "$LINENO"; then : + ac_cv_prog_objc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_objc_werror_flag=$ac_save_objc_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_objc_g" >&5 +$as_echo "$ac_cv_prog_objc_g" >&6; } +if test "$ac_test_OBJCFLAGS" = set; then + OBJCFLAGS=$ac_save_OBJCFLAGS +elif test $ac_cv_prog_objc_g = yes; then + if test "$GOBJC" = yes; then + OBJCFLAGS="-g -O2" + else + OBJCFLAGS="-g" + fi +else + if test "$GOBJC" = yes; then + OBJCFLAGS="-O2" + else + OBJCFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ac_ext=m +ac_cpp='$OBJCPP $CPPFLAGS' +ac_compile='$OBJC -c $OBJCFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$OBJC -o conftest$ac_exeext $OBJCFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_objc_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the Objective C preprocessor" >&5 +$as_echo_n "checking how to run the Objective C preprocessor... " >&6; } +if test -z "$OBJCPP"; then + if ${ac_cv_prog_OBJCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because OBJCPP needs to be expanded + for OBJCPP in "$OBJC -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_objc_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_objc_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_objc_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_OBJCPP=$OBJCPP + +fi + OBJCPP=$ac_cv_prog_OBJCPP +else + ac_cv_prog_OBJCPP=$OBJCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJCPP" >&5 +$as_echo "$OBJCPP" >&6; } +ac_preproc_ok=false +for ac_objc_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_objc_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_objc_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Objective C preprocessor \"$OBJCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ac_ext=mm +ac_cpp='$OBJCXXCPP $CPPFLAGS' +ac_compile='$OBJCXX -c $OBJCXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$OBJCXX -o conftest$ac_exeext $OBJCXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_objcxx_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in g++ objc++ objcxx c++ CXX + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJCXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJCXX"; then + ac_cv_prog_OBJCXX="$OBJCXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJCXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJCXX=$ac_cv_prog_OBJCXX +if test -n "$OBJCXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJCXX" >&5 +$as_echo "$OBJCXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$OBJCXX" && break + done +fi +if test -z "$OBJCXX"; then + ac_ct_OBJCXX=$OBJCXX + for ac_prog in g++ objc++ objcxx c++ CXX +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJCXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJCXX"; then + ac_cv_prog_ac_ct_OBJCXX="$ac_ct_OBJCXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJCXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJCXX=$ac_cv_prog_ac_ct_OBJCXX +if test -n "$ac_ct_OBJCXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJCXX" >&5 +$as_echo "$ac_ct_OBJCXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_OBJCXX" && break +done + + if test "x$ac_ct_OBJCXX" = x; then + OBJCXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJCXX=$ac_ct_OBJCXX + fi +fi + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for Objective C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU Objective C++ compiler... " >&6; } +if ${ac_cv_objcxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_objcxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_objcxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objcxx_compiler_gnu" >&5 +$as_echo "$ac_cv_objcxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GOBJCXX=yes +else + GOBJCXX= +fi +ac_test_OBJCXXFLAGS=${OBJCXXFLAGS+set} +ac_save_OBJCXXFLAGS=$OBJCXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJCXX accepts -g" >&5 +$as_echo_n "checking whether $OBJCXX accepts -g... " >&6; } +if ${ac_cv_prog_objcxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_objcxx_werror_flag=$ac_objcxx_werror_flag + ac_objcxx_werror_flag=yes + ac_cv_prog_objcxx_g=no + OBJCXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_objcxx_try_compile "$LINENO"; then : + ac_cv_prog_objcxx_g=yes +else + OBJCXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_objcxx_try_compile "$LINENO"; then : + +else + ac_objcxx_werror_flag=$ac_save_objcxx_werror_flag + OBJCXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_objcxx_try_compile "$LINENO"; then : + ac_cv_prog_objcxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_objcxx_werror_flag=$ac_save_objcx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_objcxx_g" >&5 +$as_echo "$ac_cv_prog_objcxx_g" >&6; } +if test "$ac_test_OBJCXXFLAGS" = set; then + OBJCXXFLAGS=$ac_save_OBJCXXFLAGS +elif test $ac_cv_prog_objcxx_g = yes; then + if test "$GOBJCXX" = yes; then + OBJCXXFLAGS="-g -O2" + else + OBJCXXFLAGS="-g" + fi +else + if test "$GOBJCXX" = yes; then + OBJCXXFLAGS="-O2" + else + OBJCXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ac_ext=mm +ac_cpp='$OBJCXXCPP $CPPFLAGS' +ac_compile='$OBJCXX -c $OBJCXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$OBJCXX -o conftest$ac_exeext $OBJCXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_objcxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the Objective C++ preprocessor" >&5 +$as_echo_n "checking how to run the Objective C++ preprocessor... " >&6; } +if test -z "$OBJCXXCPP"; then + if ${ac_cv_prog_OBJCXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because OBJCXXCPP needs to be expanded + for OBJCXXCPP in "$OBJCXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_objcxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_objcxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_objcxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_OBJCXXCPP=$OBJCXXCPP + +fi + OBJCXXCPP=$ac_cv_prog_OBJCXXCPP +else + ac_cv_prog_OBJCXXCPP=$OBJCXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJCXXCPP" >&5 +$as_echo "$OBJCXXCPP" >&6; } +ac_preproc_ok=false +for ac_objcxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_objcxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_objcxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Objective C++ preprocessor \"$OBJCXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + OBJCXXFLAGS="$OBJCXXFLAGS -std=c++11" +fi + +if test $HAVE_LINUX = yes ; then + LDFLAGS="$LDFLAGS -Wl,-z,defs" +fi + +if test $HAVE_MSWINDOWS = yes ; then + +$as_echo "#define __USE_MINGW_ANSI_STDIO 1" >>confdefs.h + + CFLAGS="$CFLAGS -march=i686" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + BIGENDIAN=1;; #( + no) + BIGENDIAN=0 ;; #( + universal) + as_fn_error $? "Universal builds are not supported, sorry" "$LINENO" 5 + ;; #( + *) + as_fn_error $? "Unknown machine byte order" "$LINENO" 5 ;; + esac + + + +if test "x$HAVE_MSWINDOWS" = "xyes" ; then + EXPORT="__declspec(dllexport)" +elif test "x$GCC" = "xyes" ; then + CFLAGS="$CFLAGS -fvisibility=hidden" + CXXFLAGS="$CXXFLAGS -fvisibility=hidden" + EXPORT="__attribute__((visibility(\"default\")))" +else + as_fn_error $? "Unknown syntax for EXPORT keyword" "$LINENO" 5 +fi + +cat >>confdefs.h <<_ACEOF +#define EXPORT $EXPORT +_ACEOF + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# Extract the first word of "rm", so it can be a program name with args. +set dummy rm; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_RM+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $RM in + [\\/]* | ?:[\\/]*) + ac_cv_path_RM="$RM" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +RM=$ac_cv_path_RM +if test -n "$RM"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RM" >&5 +$as_echo "$RM" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "mv", so it can be a program name with args. +set dummy mv; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MV+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MV in + [\\/]* | ?:[\\/]*) + ac_cv_path_MV="$MV" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MV="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MV=$ac_cv_path_MV +if test -n "$MV"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MV" >&5 +$as_echo "$MV" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "cp", so it can be a program name with args. +set dummy cp; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_CP+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $CP in + [\\/]* | ?:[\\/]*) + ac_cv_path_CP="$CP" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +CP=$ac_cv_path_CP +if test -n "$CP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CP" >&5 +$as_echo "$CP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_AR="$AR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_AR="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +AR=$ac_cv_path_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_AR"; then + ac_pt_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_AR="$ac_pt_AR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_AR="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_AR=$ac_cv_path_ac_pt_AR +if test -n "$ac_pt_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_AR" >&5 +$as_echo "$ac_pt_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_pt_AR + fi +else + AR="$ac_cv_path_AR" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $RANLIB in + [\\/]* | ?:[\\/]*) + ac_cv_path_RANLIB="$RANLIB" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_RANLIB="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +RANLIB=$ac_cv_path_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_RANLIB"; then + ac_pt_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_RANLIB in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_RANLIB="$ac_pt_RANLIB" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_RANLIB="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_RANLIB=$ac_cv_path_ac_pt_RANLIB +if test -n "$ac_pt_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_RANLIB" >&5 +$as_echo "$ac_pt_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_RANLIB" = x; then + RANLIB="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_pt_RANLIB + fi +else + RANLIB="$ac_cv_path_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. +set dummy ${ac_tool_prefix}windres; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_WINDRES+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $WINDRES in + [\\/]* | ?:[\\/]*) + ac_cv_path_WINDRES="$WINDRES" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_WINDRES="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +WINDRES=$ac_cv_path_WINDRES +if test -n "$WINDRES"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDRES" >&5 +$as_echo "$WINDRES" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_WINDRES"; then + ac_pt_WINDRES=$WINDRES + # Extract the first word of "windres", so it can be a program name with args. +set dummy windres; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_WINDRES+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_WINDRES in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_WINDRES="$ac_pt_WINDRES" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_WINDRES="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_WINDRES=$ac_cv_path_ac_pt_WINDRES +if test -n "$ac_pt_WINDRES"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_WINDRES" >&5 +$as_echo "$ac_pt_WINDRES" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_WINDRES" = x; then + WINDRES="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + WINDRES=$ac_pt_WINDRES + fi +else + WINDRES="$ac_cv_path_WINDRES" +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 +$as_echo_n "checking for library containing pthread_create... " >&6; } +if ${ac_cv_search_pthread_create+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +for ac_lib in '' pthread; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_pthread_create=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_pthread_create+:} false; then : + break +fi +done +if ${ac_cv_search_pthread_create+:} false; then : + +else + ac_cv_search_pthread_create=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5 +$as_echo "$ac_cv_search_pthread_create" >&6; } +ac_res=$ac_cv_search_pthread_create +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLIB" >&5 +$as_echo_n "checking for GLIB... " >&6; } + +if test -n "$GLIB_CFLAGS"; then + pkg_cv_GLIB_CFLAGS="$GLIB_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.32\""; } >&5 + ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.32") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GLIB_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= 2.32" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$GLIB_LIBS"; then + pkg_cv_GLIB_LIBS="$GLIB_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.32\""; } >&5 + ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.32") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GLIB_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= 2.32" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glib-2.0 >= 2.32" 2>&1` + else + GLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glib-2.0 >= 2.32" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$GLIB_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (glib-2.0 >= 2.32) were not met: + +$GLIB_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables GLIB_CFLAGS +and GLIB_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables GLIB_CFLAGS +and GLIB_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + GLIB_CFLAGS=$pkg_cv_GLIB_CFLAGS + GLIB_LIBS=$pkg_cv_GLIB_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GMODULE" >&5 +$as_echo_n "checking for GMODULE... " >&6; } + +if test -n "$GMODULE_CFLAGS"; then + pkg_cv_GMODULE_CFLAGS="$GMODULE_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gmodule-2.0 >= 2.32\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gmodule-2.0 >= 2.32") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GMODULE_CFLAGS=`$PKG_CONFIG --cflags "gmodule-2.0 >= 2.32" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$GMODULE_LIBS"; then + pkg_cv_GMODULE_LIBS="$GMODULE_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gmodule-2.0 >= 2.32\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gmodule-2.0 >= 2.32") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GMODULE_LIBS=`$PKG_CONFIG --libs "gmodule-2.0 >= 2.32" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GMODULE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gmodule-2.0 >= 2.32" 2>&1` + else + GMODULE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gmodule-2.0 >= 2.32" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$GMODULE_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (gmodule-2.0 >= 2.32) were not met: + +$GMODULE_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables GMODULE_CFLAGS +and GMODULE_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables GMODULE_CFLAGS +and GMODULE_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + GMODULE_CFLAGS=$pkg_cv_GMODULE_CFLAGS + GMODULE_LIBS=$pkg_cv_GMODULE_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + + +$as_echo "#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_32" >>confdefs.h + + + +# Check whether --enable-gtk was given. +if test "${enable_gtk+set}" = set; then : + enableval=$enable_gtk; USE_GTK=$enableval +else + USE_GTK=no +fi + + +if test $USE_GTK = yes ; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK" >&5 +$as_echo_n "checking for GTK... " >&6; } + +if test -n "$GTK_CFLAGS"; then + pkg_cv_GTK_CFLAGS="$GTK_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.24\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.24") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GTK_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0 >= 2.24" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$GTK_LIBS"; then + pkg_cv_GTK_LIBS="$GTK_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.24\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.24") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GTK_LIBS=`$PKG_CONFIG --libs "gtk+-2.0 >= 2.24" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-2.0 >= 2.24" 2>&1` + else + GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-2.0 >= 2.24" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$GTK_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (gtk+-2.0 >= 2.24) were not met: + +$GTK_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables GTK_CFLAGS +and GTK_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables GTK_CFLAGS +and GTK_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + GTK_CFLAGS=$pkg_cv_GTK_CFLAGS + GTK_LIBS=$pkg_cv_GTK_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +$as_echo "#define USE_GTK 1" >>confdefs.h + +fi + + + +if test $HAVE_MSWINDOWS = yes ; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GIO" >&5 +$as_echo_n "checking for GIO... " >&6; } + +if test -n "$GIO_CFLAGS"; then + pkg_cv_GIO_CFLAGS="$GIO_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gio-2.0 >= 2.32\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gio-2.0 >= 2.32") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GIO_CFLAGS=`$PKG_CONFIG --cflags "gio-2.0 >= 2.32" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$GIO_LIBS"; then + pkg_cv_GIO_LIBS="$GIO_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gio-2.0 >= 2.32\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gio-2.0 >= 2.32") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GIO_LIBS=`$PKG_CONFIG --libs "gio-2.0 >= 2.32" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gio-2.0 >= 2.32" 2>&1` + else + GIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gio-2.0 >= 2.32" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$GIO_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (gio-2.0 >= 2.32) were not met: + +$GIO_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables GIO_CFLAGS +and GIO_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables GIO_CFLAGS +and GIO_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + GIO_CFLAGS=$pkg_cv_GIO_CFLAGS + GIO_LIBS=$pkg_cv_GIO_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi +else + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GIO" >&5 +$as_echo_n "checking for GIO... " >&6; } + +if test -n "$GIO_CFLAGS"; then + pkg_cv_GIO_CFLAGS="$GIO_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gio-2.0 >= 2.32 gio-unix-2.0 >= 2.32\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gio-2.0 >= 2.32 gio-unix-2.0 >= 2.32") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GIO_CFLAGS=`$PKG_CONFIG --cflags "gio-2.0 >= 2.32 gio-unix-2.0 >= 2.32" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$GIO_LIBS"; then + pkg_cv_GIO_LIBS="$GIO_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gio-2.0 >= 2.32 gio-unix-2.0 >= 2.32\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gio-2.0 >= 2.32 gio-unix-2.0 >= 2.32") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GIO_LIBS=`$PKG_CONFIG --libs "gio-2.0 >= 2.32 gio-unix-2.0 >= 2.32" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gio-2.0 >= 2.32 gio-unix-2.0 >= 2.32" 2>&1` + else + GIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gio-2.0 >= 2.32 gio-unix-2.0 >= 2.32" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$GIO_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (gio-2.0 >= 2.32 gio-unix-2.0 >= 2.32) were not met: + +$GIO_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables GIO_CFLAGS +and GIO_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables GIO_CFLAGS +and GIO_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + GIO_CFLAGS=$pkg_cv_GIO_CFLAGS + GIO_LIBS=$pkg_cv_GIO_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi +fi + + + + + + + + + + + +# Check whether --enable-qt was given. +if test "${enable_qt+set}" = set; then : + enableval=$enable_qt; USE_QT=$enableval +else + USE_QT=yes +fi + + +if test $USE_QT = yes ; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for QTCORE" >&5 +$as_echo_n "checking for QTCORE... " >&6; } + +if test -n "$QTCORE_CFLAGS"; then + pkg_cv_QTCORE_CFLAGS="$QTCORE_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Core >= 5.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "Qt5Core >= 5.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_QTCORE_CFLAGS=`$PKG_CONFIG --cflags "Qt5Core >= 5.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$QTCORE_LIBS"; then + pkg_cv_QTCORE_LIBS="$QTCORE_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Core >= 5.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "Qt5Core >= 5.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_QTCORE_LIBS=`$PKG_CONFIG --libs "Qt5Core >= 5.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + QTCORE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "Qt5Core >= 5.2" 2>&1` + else + QTCORE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "Qt5Core >= 5.2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$QTCORE_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (Qt5Core >= 5.2) were not met: + +$QTCORE_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables QTCORE_CFLAGS +and QTCORE_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables QTCORE_CFLAGS +and QTCORE_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + QTCORE_CFLAGS=$pkg_cv_QTCORE_CFLAGS + QTCORE_LIBS=$pkg_cv_QTCORE_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +if test -n "$QTBINPATH"; then + pkg_cv_QTBINPATH="$QTBINPATH" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Core >= 5.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "Qt5Core >= 5.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_QTBINPATH=`$PKG_CONFIG --variable="host_bins" "Qt5Core >= 5.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +QTBINPATH=$pkg_cv_QTBINPATH + +if test "x$QTBINPATH" = x""; then : + +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for QT" >&5 +$as_echo_n "checking for QT... " >&6; } + +if test -n "$QT_CFLAGS"; then + pkg_cv_QT_CFLAGS="$QT_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Core Qt5Gui Qt5Widgets >= 5.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "Qt5Core Qt5Gui Qt5Widgets >= 5.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_QT_CFLAGS=`$PKG_CONFIG --cflags "Qt5Core Qt5Gui Qt5Widgets >= 5.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$QT_LIBS"; then + pkg_cv_QT_LIBS="$QT_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"Qt5Core Qt5Gui Qt5Widgets >= 5.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "Qt5Core Qt5Gui Qt5Widgets >= 5.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_QT_LIBS=`$PKG_CONFIG --libs "Qt5Core Qt5Gui Qt5Widgets >= 5.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + QT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "Qt5Core Qt5Gui Qt5Widgets >= 5.2" 2>&1` + else + QT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "Qt5Core Qt5Gui Qt5Widgets >= 5.2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$QT_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (Qt5Core Qt5Gui Qt5Widgets >= 5.2) were not met: + +$QT_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables QT_CFLAGS +and QT_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables QT_CFLAGS +and QT_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + QT_CFLAGS=$pkg_cv_QT_CFLAGS + QT_LIBS=$pkg_cv_QT_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +$as_echo "#define USE_QT 1" >>confdefs.h + + +$as_echo "#define QT_NO_DEPRECATED_WARNINGS 1" >>confdefs.h + + + # needed if Qt was built with -reduce-relocations + QTCORE_CFLAGS="$QTCORE_CFLAGS -fPIC" + QT_CFLAGS="$QT_CFLAGS -fPIC" +fi + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library system" >&5 +$as_echo_n "checking for shared library system... " >&6; } + case "$host_os" in + darwin*) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Darwin" >&5 +$as_echo "Darwin" >&6; } + LIB_CFLAGS='-fPIC -DPIC' + LIB_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}' + LIB_LDFLAGS_INSTALL_NAME='-Wl,-install_name,${libdir}/$${out%.dylib}.${LIB_MAJOR}.dylib' + LIB_PREFIX='lib' + LIB_SUFFIX='.dylib' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CFLAGS='-fPIC -DPIC' + PLUGIN_LDFLAGS='-bundle -undefined dynamic_lookup' + PLUGIN_SUFFIX='.bundle' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib' + CLEAN_LIB='' + ;; + mingw* | cygwin*) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: MinGW / Cygwin" >&5 +$as_echo "MinGW / Cygwin" >&6; } + LIB_CFLAGS='' + LIB_LDFLAGS='-shared -Wl,--export-all-symbols,--out-implib,${SHARED_LIB}.a' + LIB_LDFLAGS_INSTALL_NAME='' + LIB_PREFIX='lib' + LIB_SUFFIX='.dll' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CFLAGS='' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.dll' + INSTALL_LIB='&& ${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i && ${INSTALL} -m 755 $$i.a ${DESTDIR}${libdir}/$$i.a' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/$$i.a' + CLEAN_LIB='${SHARED_LIB}.a' + ;; + openbsd* | mirbsd*) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenBSD" >&5 +$as_echo "OpenBSD" >&6; } + LIB_CFLAGS='-fPIC -DPIC' + LIB_LDFLAGS='-shared' + LIB_LDFLAGS_INSTALL_NAME='' + LIB_PREFIX='lib' + LIB_SUFFIX='.so.${LIB_MAJOR}.${LIB_MINOR}' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CFLAGS='-fPIC -DPIC' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.so' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i' + CLEAN_LIB='' + ;; + solaris*) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Solaris" >&5 +$as_echo "Solaris" >&6; } + LIB_CFLAGS='-fPIC -DPIC' + LIB_LDFLAGS='-shared -Wl,-soname=${SHARED_LIB}.${LIB_MAJOR}.${LIB_MINOR}' + LIB_LDFLAGS_INSTALL_NAME='' + LIB_PREFIX='lib' + LIB_SUFFIX='.so' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CFLAGS='-fPIC -DPIC' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.so' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR} && rm -f ${DESTDIR}${libdir}/$$i && ${LN_S} $$i.${LIB_MAJOR}.${LIB_MINOR} ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}' + CLEAN_LIB='' + ;; + *-android*) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Android" >&5 +$as_echo "Android" >&6; } + LIB_CFLAGS='-fPIC -DPIC' + LIB_LDFLAGS='-shared -Wl,-soname=${SHARED_LIB}.${LIB_MAJOR}' + LIB_LDFLAGS_INSTALL_NAME='' + LIB_PREFIX='lib' + LIB_SUFFIX='.so' + LDFLAGS_RPATH='' + PLUGIN_CFLAGS='-fPIC -DPIC' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.so' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0 && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0' + CLEAN_LIB='' + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ELF" >&5 +$as_echo "ELF" >&6; } + LIB_CFLAGS='-fPIC -DPIC' + LIB_LDFLAGS='-shared -Wl,-soname=${SHARED_LIB}.${LIB_MAJOR}' + LIB_LDFLAGS_INSTALL_NAME='' + LIB_PREFIX='lib' + LIB_SUFFIX='.so' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CFLAGS='-fPIC -DPIC' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.so' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0 && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0' + CLEAN_LIB='' + ;; + esac + + + + + + + + + + + + + + + +cat >>confdefs.h <<_ACEOF +#define PLUGIN_SUFFIX "$PLUGIN_SUFFIX" +_ACEOF + + + + + +# Check whether --with-pkgconfigdir was given. +if test "${with_pkgconfigdir+set}" = set; then : + withval=$with_pkgconfigdir; +else + with_pkgconfigdir='${libdir}/pkgconfig' +fi + +pkgconfigdir=$with_pkgconfigdir + + + + + + +for ac_func in sigwait +do : + ac_fn_c_check_func "$LINENO" "sigwait" "ac_cv_func_sigwait" +if test "x$ac_cv_func_sigwait" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SIGWAIT 1 +_ACEOF + +fi +done + + + + + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld" >&5 +$as_echo_n "checking for ld... " >&6; } +elif test "$GCC" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test -n "$LD"; then + # Let the user override the test with a path. + : +else + if ${acl_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + + acl_cv_path_LD= # Final result of this test + ac_prog=ld # Program to search in $PATH + if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + acl_output=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + acl_output=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $acl_output in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'` + while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do + acl_output=`echo $acl_output | sed "s%$re_direlt%/%"` + done + # Got the pathname. No search in PATH is needed. + acl_cv_path_LD="$acl_output" + ac_prog= + ;; + "") + # If it fails, then pretend we aren't using GCC. + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + fi + if test -n "$ac_prog"; then + # Search for $ac_prog in $PATH. + acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 conftest.$ac_ext +/* end confdefs.h. */ +#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # The compiler produces 64-bit code. Add option '-b64' so that the + # linker groks 64-bit object files. + case "$acl_cv_path_LD " in + *" -b64 "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -b64" ;; + esac + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + sparc64-*-netbsd*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + # The compiler produces 32-bit code. Add option '-m elf32_sparc' + # so that the linker groks 32-bit object files. + case "$acl_cv_path_LD " in + *" -m elf32_sparc "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -m elf32_sparc" ;; + esac + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + esac + +fi + + LD="$acl_cv_path_LD" +fi +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${acl_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$acl_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$acl_cv_prog_gnu_ld + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 +$as_echo_n "checking for shared library run path origin... " >&6; } +if ${acl_cv_rpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 +$as_echo "$acl_cv_rpath" >&6; } + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + # Check whether --enable-rpath was given. +if test "${enable_rpath+set}" = set; then : + enableval=$enable_rpath; : +else + enable_rpath=yes +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking 32-bit host C ABI" >&5 +$as_echo_n "checking 32-bit host C ABI... " >&6; } +if ${gl_cv_host_cpu_c_abi_32bit+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$gl_cv_host_cpu_c_abi"; then + case "$gl_cv_host_cpu_c_abi" in + i386 | x86_64-x32 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | riscv*-ilp32* | s390 | sparc) + gl_cv_host_cpu_c_abi_32bit=yes ;; + x86_64 | alpha | arm64 | hppa64 | ia64 | mips64 | powerpc64 | powerpc64-elfv2 | riscv*-lp64* | s390x | sparc64 ) + gl_cv_host_cpu_c_abi_32bit=no ;; + *) + gl_cv_host_cpu_c_abi_32bit=unknown ;; + esac + else + case "$host_cpu" in + + # CPUs that only support a 32-bit ABI. + arc \ + | bfin \ + | cris* \ + | csky \ + | epiphany \ + | ft32 \ + | h8300 \ + | m68k \ + | microblaze | microblazeel \ + | nds32 | nds32le | nds32be \ + | nios2 | nios2eb | nios2el \ + | or1k* \ + | or32 \ + | sh | sh1234 | sh1234elb \ + | tic6x \ + | xtensa* ) + gl_cv_host_cpu_c_abi_32bit=yes + ;; + + # CPUs that only support a 64-bit ABI. + alpha | alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] \ + | mmix ) + gl_cv_host_cpu_c_abi_32bit=no + ;; + + i[34567]86 ) + gl_cv_host_cpu_c_abi_32bit=yes + ;; + + x86_64 ) + # On x86_64 systems, the C compiler may be generating code in one of + # these ABIs: + # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64. + # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64 + # with native Windows (mingw, MSVC). + # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if (defined __x86_64__ || defined __amd64__ \ + || defined _M_X64 || defined _M_AMD64) \ + && !(defined __ILP32__ || defined _ILP32) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + arm* | aarch64 ) + # Assume arm with EABI. + # On arm64 systems, the C compiler may be generating code in one of + # these ABIs: + # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64. + # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __aarch64__ && !(defined __ILP32__ || defined _ILP32) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + hppa1.0 | hppa1.1 | hppa2.0* | hppa64 ) + # On hppa, the C compiler may be generating 32-bit code or 64-bit + # code. In the latter case, it defines _LP64 and __LP64__. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __LP64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + ia64* ) + # On ia64 on HP-UX, the C compiler may be generating 64-bit code or + # 32-bit code. In the latter case, it defines _ILP32. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef _ILP32 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=yes +else + gl_cv_host_cpu_c_abi_32bit=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + mips* ) + # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this + # at 32. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + powerpc* ) + # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD. + # No need to distinguish them here; the caller may distinguish + # them based on the OS. + # On powerpc64 systems, the C compiler may still be generating + # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may + # be generating 64-bit code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + rs6000 ) + gl_cv_host_cpu_c_abi_32bit=yes + ;; + + riscv32 | riscv64 ) + # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d. + # Size of 'long' and 'void *': + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __LP64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + s390* ) + # On s390x, the C compiler may be generating 64-bit (= s390x) code + # or 31-bit (= s390) code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __LP64__ || defined __s390x__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + sparc | sparc64 ) + # UltraSPARCs running Linux have `uname -m` = "sparc64", but the + # C compiler still generates 32-bit code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi_32bit=no +else + gl_cv_host_cpu_c_abi_32bit=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + *) + gl_cv_host_cpu_c_abi_32bit=unknown + ;; + esac + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_host_cpu_c_abi_32bit" >&5 +$as_echo "$gl_cv_host_cpu_c_abi_32bit" >&6; } + + HOST_CPU_C_ABI_32BIT="$gl_cv_host_cpu_c_abi_32bit" + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ELF binary format" >&5 +$as_echo_n "checking for ELF binary format... " >&6; } +if ${gl_cv_elf+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __ELF__ + Extensible Linking Format + #endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "Extensible Linking Format" >/dev/null 2>&1; then : + gl_cv_elf=yes +else + gl_cv_elf=no +fi +rm -f conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_elf" >&5 +$as_echo "$gl_cv_elf" >&6; } + if test $gl_cv_elf; then + # Extract the ELF class of a file (5th byte) in decimal. + # Cf. https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header + if od -A x < /dev/null >/dev/null 2>/dev/null; then + # Use POSIX od. + func_elfclass () + { + od -A n -t d1 -j 4 -N 1 + } + else + # Use BSD hexdump. + func_elfclass () + { + dd bs=1 count=1 skip=4 2>/dev/null | hexdump -e '1/1 "%3d "' + echo + } + fi + case $HOST_CPU_C_ABI_32BIT in + yes) + # 32-bit ABI. + acl_is_expected_elfclass () + { + test "`func_elfclass | sed -e 's/[ ]//g'`" = 1 + } + ;; + no) + # 64-bit ABI. + acl_is_expected_elfclass () + { + test "`func_elfclass | sed -e 's/[ ]//g'`" = 2 + } + ;; + *) + # Unknown. + acl_is_expected_elfclass () + { + : + } + ;; + esac + else + acl_is_expected_elfclass () + { + : + } + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the common suffixes of directories in the library search path" >&5 +$as_echo_n "checking for the common suffixes of directories in the library search path... " >&6; } +if ${acl_cv_libdirstems+:} false; then : + $as_echo_n "(cached) " >&6 +else + acl_libdirstem=lib + acl_libdirstem2= + acl_libdirstem3= + case "$host_os" in + solaris*) + if test $HOST_CPU_C_ABI_32BIT = no; then + acl_libdirstem2=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem3=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem3=lib/amd64 ;; + esac + fi + ;; + *) + searchpath=`(LC_ALL=C $CC $CPPFLAGS $CFLAGS -print-search-dirs) 2>/dev/null \ + | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test $HOST_CPU_C_ABI_32BIT != no; then + # 32-bit or unknown ABI. + if test -d /usr/lib32; then + acl_libdirstem2=lib32 + fi + fi + if test $HOST_CPU_C_ABI_32BIT != yes; then + # 64-bit or unknown ABI. + if test -d /usr/lib64; then + acl_libdirstem3=lib64 + fi + fi + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib32/ | */lib32 ) acl_libdirstem2=lib32 ;; + */lib64/ | */lib64 ) acl_libdirstem3=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib32 ) acl_libdirstem2=lib32 ;; + */lib64 ) acl_libdirstem3=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + if test $HOST_CPU_C_ABI_32BIT = yes; then + # 32-bit ABI. + acl_libdirstem3= + fi + if test $HOST_CPU_C_ABI_32BIT = no; then + # 64-bit ABI. + acl_libdirstem2= + fi + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + test -n "$acl_libdirstem3" || acl_libdirstem3="$acl_libdirstem" + acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2,$acl_libdirstem3" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_libdirstems" >&5 +$as_echo "$acl_cv_libdirstems" >&6; } + acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'` + acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,//' -e 's/,.*//'` + acl_libdirstem3=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,[^,]*,//' -e 's/,.*//'` + + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libiconv-prefix was given. +if test "${with_libiconv_prefix+set}" = set; then : + withval=$with_libiconv_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + additional_libdir2="$withval/$acl_libdirstem2" + additional_libdir3="$withval/$acl_libdirstem3" + fi + fi + +fi + + if test "X$additional_libdir2" = "X$additional_libdir"; then + additional_libdir2= + fi + if test "X$additional_libdir3" = "X$additional_libdir"; then + additional_libdir3= + fi + LIBICONV= + LTLIBICONV= + INCICONV= + LIBICONV_PREFIX= + HAVE_LIBICONV= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='iconv ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + for additional_libdir_variable in additional_libdir additional_libdir2 additional_libdir3; do + if test "X$found_dir" = "X"; then + eval dir=\$$additional_libdir_variable + if test -n "$dir"; then + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + fi + done + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem3"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$acl_hardcode_direct" = yes; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = 'iconv'; then + LIBICONV_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = 'iconv'; then + LIBICONV_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem3 | */$acl_libdirstem3/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem3/"'*$,,'` + if test "$name" = 'iconv'; then + LIBICONV_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + dependency_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$dependency_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem2" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem3"; then + haveit= + if test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem2" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem3"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$dependency_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$dependency_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" + ;; + esac + done + fi + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" + done + fi + + + + + + + + + + + + am_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCICONV; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 +$as_echo_n "checking for iconv... " >&6; } +if ${am_cv_func_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_lib_iconv=yes + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$am_save_LIBS" + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 +$as_echo "$am_cv_func_iconv" >&6; } + if test "$am_cv_func_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 +$as_echo_n "checking for working iconv... " >&6; } +if ${am_cv_func_iconv_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + am_cv_func_iconv_works=no + for ac_iconv_const in '' 'const'; do + if test "$cross_compiling" = yes; then : + case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +#ifndef ICONV_CONST +# define ICONV_CONST $ac_iconv_const +#endif + +int +main () +{ +int result = 0; + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 1; + iconv_close (cd_utf8_to_88591); + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\263"; + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 2; + iconv_close (cd_ascii_to_88591); + } + } + /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304"; + static char buf[2] = { (char)0xDE, (char)0xAD }; + ICONV_CONST char *inptr = input; + size_t inbytesleft = 1; + char *outptr = buf; + size_t outbytesleft = 1; + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) + result |= 4; + iconv_close (cd_88591_to_utf8); + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + result |= 8; + iconv_close (cd_88591_to_utf8); + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + { + /* Try standardized names. */ + iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP"); + /* Try IRIX, OSF/1 names. */ + iconv_t cd2 = iconv_open ("UTF-8", "eucJP"); + /* Try AIX names. */ + iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP"); + /* Try HP-UX names. */ + iconv_t cd4 = iconv_open ("utf8", "eucJP"); + if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1) + && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1)) + result |= 16; + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd2 != (iconv_t)(-1)) + iconv_close (cd2); + if (cd3 != (iconv_t)(-1)) + iconv_close (cd3); + if (cd4 != (iconv_t)(-1)) + iconv_close (cd4); + } + return result; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + am_cv_func_iconv_works=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + test "$am_cv_func_iconv_works" = no || break + done + LIBS="$am_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 +$as_echo "$am_cv_func_iconv_works" >&6; } + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + +$as_echo "#define HAVE_ICONV 1" >>confdefs.h + + fi + if test "$am_cv_lib_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 +$as_echo_n "checking how to link with libiconv... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 +$as_echo "$LIBICONV" >&6; } + else + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + + + + if test "$am_cv_func_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5 +$as_echo_n "checking for iconv declaration... " >&6; } + if ${am_cv_proto_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + am_cv_proto_iconv_arg1="" +else + am_cv_proto_iconv_arg1="const" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" +fi + + am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: + $am_cv_proto_iconv" >&5 +$as_echo " + $am_cv_proto_iconv" >&6; } + else + am_cv_proto_iconv_arg1="" + fi + +cat >>confdefs.h <<_ACEOF +#define ICONV_CONST $am_cv_proto_iconv_arg1 +_ACEOF + + + +LIBS="$LIBS $LIBICONV" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 +$as_echo_n "checking whether NLS is requested... " >&6; } + # Check whether --enable-nls was given. +if test "${enable_nls+set}" = set; then : + enableval=$enable_nls; USE_NLS=$enableval +else + USE_NLS=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 +$as_echo "$USE_NLS" >&6; } + + + + + GETTEXT_MACRO_VERSION=0.20 + + + + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$MSGFMT" in + [\\/]* | ?:[\\/]*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test "$MSGFMT" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 +$as_echo "$MSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_GMSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GMSGFMT in + [\\/]* | ?:[\\/]*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT=$ac_cv_path_GMSGFMT +if test -n "$GMSGFMT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 +$as_echo "$GMSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; + *) GMSGFMT_015=$GMSGFMT ;; + esac + + + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_XGETTEXT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$XGETTEXT" in + [\\/]* | ?:[\\/]*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test "$XGETTEXT" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 +$as_echo "$XGETTEXT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + rm -f messages.po + + case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; + *) XGETTEXT_015=$XGETTEXT ;; + esac + + + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "msgmerge", so it can be a program name with args. +set dummy msgmerge; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MSGMERGE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$MSGMERGE" in + [\\/]* | ?:[\\/]*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then + ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" + ;; +esac +fi +MSGMERGE="$ac_cv_path_MSGMERGE" +if test "$MSGMERGE" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 +$as_echo "$MSGMERGE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if LC_ALL=C $MSGMERGE --help | grep ' --for-msgfmt ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--for-msgfmt' + else + if LC_ALL=C $MSGMERGE --help | grep ' --no-fuzzy-matching ' >/dev/null; then + MSGMERGE_FOR_MSGFMT_OPTION='--no-fuzzy-matching --no-location --quiet' + else + MSGMERGE_FOR_MSGFMT_OPTION='--no-location --quiet' + fi + fi + + + test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= + + + ac_config_commands="$ac_config_commands po-directories" + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5 +$as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; } +if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +CFPreferencesCopyAppValue(NULL, NULL) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gt_cv_func_CFPreferencesCopyAppValue=yes +else + gt_cv_func_CFPreferencesCopyAppValue=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$gt_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 +$as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; } + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + +$as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyPreferredLanguages" >&5 +$as_echo_n "checking for CFLocaleCopyPreferredLanguages... " >&6; } +if ${gt_cv_func_CFLocaleCopyPreferredLanguages+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +CFLocaleCopyPreferredLanguages(); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gt_cv_func_CFLocaleCopyPreferredLanguages=yes +else + gt_cv_func_CFLocaleCopyPreferredLanguages=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$gt_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyPreferredLanguages" >&5 +$as_echo "$gt_cv_func_CFLocaleCopyPreferredLanguages" >&6; } + if test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then + +$as_echo "#define HAVE_CFLOCALECOPYPREFERREDLANGUAGES 1" >>confdefs.h + + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes \ + || test $gt_cv_func_CFLocaleCopyPreferredLanguages = yes; then + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" + fi + + + + + + + LIBINTL= + LTLIBINTL= + POSUB= + + case " $gt_needs " in + *" need-formatstring-macros "*) gt_api_version=3 ;; + *" need-ngettext "*) gt_api_version=2 ;; + *) gt_api_version=1 ;; + esac + gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" + gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" + + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + + + if test $gt_api_version -ge 3; then + gt_revision_test_code=' +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +' + else + gt_revision_test_code= + fi + if test $gt_api_version -ge 2; then + gt_expression_test_code=' + * ngettext ("", "", 0)' + else + gt_expression_test_code= + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5 +$as_echo_n "checking for GNU gettext in libc... " >&6; } +if eval \${$gt_func_gnugettext_libc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings; +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + +int +main () +{ + +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$gt_func_gnugettext_libc=yes" +else + eval "$gt_func_gnugettext_libc=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$gt_func_gnugettext_libc + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + + + + + + am_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCICONV; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 +$as_echo_n "checking for iconv... " >&6; } +if ${am_cv_func_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_lib_iconv=yes + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$am_save_LIBS" + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 +$as_echo "$am_cv_func_iconv" >&6; } + if test "$am_cv_func_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 +$as_echo_n "checking for working iconv... " >&6; } +if ${am_cv_func_iconv_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + am_cv_func_iconv_works=no + for ac_iconv_const in '' 'const'; do + if test "$cross_compiling" = yes; then : + case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +#ifndef ICONV_CONST +# define ICONV_CONST $ac_iconv_const +#endif + +int +main () +{ +int result = 0; + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 1; + iconv_close (cd_utf8_to_88591); + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\263"; + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + result |= 2; + iconv_close (cd_ascii_to_88591); + } + } + /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304"; + static char buf[2] = { (char)0xDE, (char)0xAD }; + ICONV_CONST char *inptr = input; + size_t inbytesleft = 1; + char *outptr = buf; + size_t outbytesleft = 1; + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) + result |= 4; + iconv_close (cd_88591_to_utf8); + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + result |= 8; + iconv_close (cd_88591_to_utf8); + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + { + /* Try standardized names. */ + iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP"); + /* Try IRIX, OSF/1 names. */ + iconv_t cd2 = iconv_open ("UTF-8", "eucJP"); + /* Try AIX names. */ + iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP"); + /* Try HP-UX names. */ + iconv_t cd4 = iconv_open ("utf8", "eucJP"); + if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1) + && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1)) + result |= 16; + if (cd1 != (iconv_t)(-1)) + iconv_close (cd1); + if (cd2 != (iconv_t)(-1)) + iconv_close (cd2); + if (cd3 != (iconv_t)(-1)) + iconv_close (cd3); + if (cd4 != (iconv_t)(-1)) + iconv_close (cd4); + } + return result; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + am_cv_func_iconv_works=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + test "$am_cv_func_iconv_works" = no || break + done + LIBS="$am_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 +$as_echo "$am_cv_func_iconv_works" >&6; } + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + +$as_echo "#define HAVE_ICONV 1" >>confdefs.h + + fi + if test "$am_cv_lib_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 +$as_echo_n "checking how to link with libiconv... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 +$as_echo "$LIBICONV" >&6; } + else + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libintl-prefix was given. +if test "${with_libintl_prefix+set}" = set; then : + withval=$with_libintl_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\" + eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + additional_libdir2="$withval/$acl_libdirstem2" + additional_libdir3="$withval/$acl_libdirstem3" + fi + fi + +fi + + if test "X$additional_libdir2" = "X$additional_libdir"; then + additional_libdir2= + fi + if test "X$additional_libdir3" = "X$additional_libdir"; then + additional_libdir3= + fi + LIBINTL= + LTLIBINTL= + INCINTL= + LIBINTL_PREFIX= + HAVE_LIBINTL= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='intl ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + for additional_libdir_variable in additional_libdir additional_libdir2 additional_libdir3; do + if test "X$found_dir" = "X"; then + eval dir=\$$additional_libdir_variable + if test -n "$dir"; then + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + fi + done + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem3"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$acl_hardcode_direct" = yes; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = 'intl'; then + LIBINTL_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = 'intl'; then + LIBINTL_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem3 | */$acl_libdirstem3/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem3/"'*$,,'` + if test "$name" = 'intl'; then + LIBINTL_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + dependency_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$dependency_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem2" \ + && test "X$dependency_libdir" != "X/usr/$acl_libdirstem3"; then + haveit= + if test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem2" \ + || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem3"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$dependency_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$dependency_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$dependency_libdir"; then + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$dependency_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" + ;; + esac + done + fi + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" + done + fi + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5 +$as_echo_n "checking for GNU gettext in libintl... " >&6; } +if eval \${$gt_func_gnugettext_libintl+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + +int +main () +{ + +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$gt_func_gnugettext_libintl=yes" +else + eval "$gt_func_gnugettext_libintl=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) +#else +#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 +#endif +$gt_revision_test_code + +int +main () +{ + +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + eval "$gt_func_gnugettext_libintl=yes" + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS" +fi +eval ac_res=\$$gt_func_gnugettext_libintl + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + fi + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ + || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools; }; then + gt_use_preinstalled_gnugettext=yes + else + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + + + if test -n "$INTL_MACOSX_LIBS"; then + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" + LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" + fi + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + + else + USE_NLS=no + fi + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5 +$as_echo_n "checking whether to use NLS... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 +$as_echo "$USE_NLS" >&6; } + if test "$USE_NLS" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5 +$as_echo_n "checking where the gettext function comes from... " >&6; } + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5 +$as_echo "$gt_source" >&6; } + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5 +$as_echo_n "checking how to link with libintl... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5 +$as_echo "$LIBINTL" >&6; } + + for element in $INCINTL; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + fi + + +$as_echo "#define HAVE_GETTEXT 1" >>confdefs.h + + +$as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h + + fi + + POSUB=po + fi + + + + INTLLIBS="$LIBINTL" + + + + + + +if test "$MSGFMT" = ":" ; then + as_fn_error $? "msgfmt was not found; have you installed gettext?" "$LINENO" 5 +fi + +LIBS="$LIBS $LIBINTL" + + +# Check whether --with-buildstamp was given. +if test "${with_buildstamp+set}" = set; then : + withval=$with_buildstamp; BUILDSTAMP="$withval" +else + BUILDSTAMP="unknown build" +fi + + + +cat >>confdefs.h <<_ACEOF +#define BUILDSTAMP "$BUILDSTAMP" +_ACEOF + + + + +# Check whether --enable-dbus was given. +if test "${enable_dbus+set}" = set; then : + enableval=$enable_dbus; USE_DBUS=$enableval +else + USE_DBUS=yes +fi + + +if test $USE_DBUS = yes ; then + # Extract the first word of "gdbus-codegen", so it can be a program name with args. +set dummy gdbus-codegen; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_have_dbus+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$have_dbus"; then + ac_cv_prog_have_dbus="$have_dbus" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_have_dbus="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_have_dbus" && ac_cv_prog_have_dbus="no" +fi +fi +have_dbus=$ac_cv_prog_have_dbus +if test -n "$have_dbus"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_dbus" >&5 +$as_echo "$have_dbus" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test $have_dbus = no ; then + as_fn_error $? "D-Bus support unavailable; use --disable-dbus for a crippled build" "$LINENO" 5 + fi + +$as_echo "#define USE_DBUS 1" >>confdefs.h + +fi + + + + +# Check whether --enable-valgrind was given. +if test "${enable_valgrind+set}" = set; then : + enableval=$enable_valgrind; enable_valgrind=$enableval +else + enable_valgrind=no +fi + + +if test $enable_valgrind = yes ; then + +$as_echo "#define VALGRIND_FRIENDLY 1" >>confdefs.h + + VALGRIND_FRIENDLY=1 +else + VALGRIND_FRIENDLY=0 +fi + + + + +plugindir="$libdir/audacious" + + +localedir="$datarootdir/locale" + + +CPPFLAGS="$CPPFLAGS -include config.h" + + +### --------------------------------------------------------------------------- + + +GENERATED_FILES="audacious.pc buildsys.mk extra.mk man/audtool.1 man/audacious.1 src/libaudcore/audio.h win32/audacious.nsi win32/override/README.txt" + + +ac_config_files="$ac_config_files audacious.pc buildsys.mk extra.mk man/audtool.1 man/audacious.1 src/libaudcore/audio.h win32/audacious.nsi win32/override/README.txt" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + + + CC_DEPENDS=$GCC + + CXX_DEPENDS=$GXX + + OBJC_DEPENDS=$GOBJC + + OBJCXX_DEPENDS=$GOBJCXX + + + # Extract the first word of "tput", so it can be a program name with args. +set dummy tput; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_TPUT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $TPUT in + [\\/]* | ?:[\\/]*) + ac_cv_path_TPUT="$TPUT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_TPUT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +TPUT=$ac_cv_path_TPUT +if test -n "$TPUT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TPUT" >&5 +$as_echo "$TPUT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + if test x"$TPUT" != x""; then : + + if x=$($TPUT el 2>/dev/null); then + TERM_EL="$x" + + else + TERM_EL="$($TPUT ce 2>/dev/null)" + + fi + + if x=$($TPUT sgr0 2>/dev/null); then + TERM_SGR0="$x" + + else + TERM_SGR0="$($TPUT me 2>/dev/null)" + + fi + + if x=$($TPUT bold 2>/dev/null); then + TERM_BOLD="$x" + + else + TERM_BOLD="$($TPUT md 2>/dev/null)" + + fi + + if x=$($TPUT setaf 1 2>/dev/null); then + TERM_SETAF1="$x" + + TERM_SETAF2="$($TPUT setaf 2 2>/dev/null)" + + TERM_SETAF3="$($TPUT setaf 3 2>/dev/null)" + + TERM_SETAF4="$($TPUT setaf 4 2>/dev/null)" + + TERM_SETAF6="$($TPUT setaf 6 2>/dev/null)" + + elif x=$($TPUT setaf 1 0 0 2>/dev/null); then + TERM_SETAF1="$x" + + TERM_SETAF2="$($TPUT setaf 2 0 0 2>/dev/null)" + + TERM_SETAF3="$($TPUT setaf 3 0 0 2>/dev/null)" + + TERM_SETAF4="$($TPUT setaf 4 0 0 2>/dev/null)" + + TERM_SETAF6="$($TPUT setaf 6 0 0 2>/dev/null)" + + else + TERM_SETAF1="$($TPUT AF 1 2>/dev/null)" + + TERM_SETAF2="$($TPUT AF 2 2>/dev/null)" + + TERM_SETAF3="$($TPUT AF 3 2>/dev/null)" + + TERM_SETAF4="$($TPUT AF 4 2>/dev/null)" + + TERM_SETAF6="$($TPUT AF 6 2>/dev/null)" + + fi + +else + + TERM_EL='\033\133K' + + TERM_SGR0='\033\133m' + + TERM_BOLD='\033\1331m' + + TERM_SETAF1='\033\13331m' + + TERM_SETAF2='\033\13332m' + + TERM_SETAF3='\033\13333m' + + TERM_SETAF4='\033\13334m' + + TERM_SETAF6='\033\13336m' + + +fi + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by audacious $as_me 4.0.5, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +audacious config.status 4.0.5 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. + OBSOLETE_ALL_LINGUAS="$ALL_LINGUAS" + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; + "audacious.pc") CONFIG_FILES="$CONFIG_FILES audacious.pc" ;; + "buildsys.mk") CONFIG_FILES="$CONFIG_FILES buildsys.mk" ;; + "extra.mk") CONFIG_FILES="$CONFIG_FILES extra.mk" ;; + "man/audtool.1") CONFIG_FILES="$CONFIG_FILES man/audtool.1" ;; + "man/audacious.1") CONFIG_FILES="$CONFIG_FILES man/audacious.1" ;; + "src/libaudcore/audio.h") CONFIG_FILES="$CONFIG_FILES src/libaudcore/audio.h" ;; + "win32/audacious.nsi") CONFIG_FILES="$CONFIG_FILES win32/audacious.nsi" ;; + "win32/override/README.txt") CONFIG_FILES="$CONFIG_FILES win32/override/README.txt" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "po-directories":C) + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + # Treat a directory as a PO directory if and only if it has a + # POTFILES.in file. This allows packages to have multiple PO + # directories under different names or in different locations. + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + gt_tab=`printf '\t'` + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + ALL_LINGUAS=$OBSOLETE_ALL_LINGUAS + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +### --------------------------------------------------------------------------- +echo "" +echo "Configuration:" +echo "" +echo " Install path: $prefix" +echo "" +echo " D-Bus support: $USE_DBUS" +echo " GTK+ support: $USE_GTK" +echo " Qt support: $USE_QT" +echo " Valgrind analysis support: $enable_valgrind" +echo "" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..5e09b28 --- /dev/null +++ b/configure.ac @@ -0,0 +1,138 @@ +dnl *** +dnl *** Process this file with autoconf to produce a configure script. +dnl *** + +dnl Initialize +dnl ========== + +AC_PREREQ([2.59]) +AC_INIT([audacious], [4.0.5]) +AC_COPYRIGHT([Copyright (C) 2001-2020 Audacious developers and others]) + +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE_NAME", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$PACKAGE_VERSION", [Version number of package]) + +COPYRIGHT="Copyright (C) 2001-2020 Audacious developers and others" +AC_DEFINE_UNQUOTED(COPYRIGHT, "$COPYRIGHT", [Copyright]) +AC_SUBST(COPYRIGHT) + +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +AUD_COMMON_PROGS + +BUILDSYS_INIT +BUILDSYS_SHARED_LIB +AC_DEFINE_UNQUOTED(PLUGIN_SUFFIX, "$PLUGIN_SUFFIX", [Suffix for plugins]) + +m4_ifdef([PKG_INSTALLDIR], [PKG_INSTALLDIR], AC_SUBST([pkgconfigdir], ${libdir}/pkgconfig)) + +dnl Headers and functions +dnl =============================== + +AC_CHECK_FUNCS([sigwait]) + +dnl iconv +dnl ===== + +AM_ICONV +LIBS="$LIBS $LIBICONV" + +dnl gettext +dnl ======= +AM_GNU_GETTEXT([external]) +if test "$MSGFMT" = ":" ; then + AC_MSG_ERROR([msgfmt was not found; have you installed gettext?]) +fi + +LIBS="$LIBS $LIBINTL" + +dnl Build stamp +dnl =========== +AC_ARG_WITH([buildstamp], + AS_HELP_STRING([--with-buildstamp=XXX], [Set build stamp to XXX]), + BUILDSTAMP="$withval", BUILDSTAMP="unknown build") + +AC_DEFINE_UNQUOTED(BUILDSTAMP, "$BUILDSTAMP", [Build stamp]) +AC_SUBST(BUILDSTAMP) + +dnl D-Bus support +dnl ============= + +AC_ARG_ENABLE(dbus, + AS_HELP_STRING(--disable-dbus, [Disable D-Bus support (default=enabled)]), + USE_DBUS=$enableval, USE_DBUS=yes) + +if test $USE_DBUS = yes ; then + AC_CHECK_PROG(have_dbus, gdbus-codegen, yes, no) + if test $have_dbus = no ; then + AC_MSG_ERROR([D-Bus support unavailable; use --disable-dbus for a crippled build]) + fi + AC_DEFINE(USE_DBUS, 1, [Define if D-Bus support enabled]) +fi + +AC_SUBST(USE_DBUS) + +dnl Valgrind analysis support +dnl ========================= + +AC_ARG_ENABLE(valgrind, + AS_HELP_STRING(--enable-valgrind, [Valgrind analysis support (default=disabled)]), + enable_valgrind=$enableval, enable_valgrind=no) + +if test $enable_valgrind = yes ; then + AC_DEFINE(VALGRIND_FRIENDLY, 1, [Define to allow Valgrind analysis]) + VALGRIND_FRIENDLY=1 +else + VALGRIND_FRIENDLY=0 +fi + +AC_SUBST([VALGRIND_FRIENDLY]) + +dnl Paths +dnl ===== + +plugindir="$libdir/audacious" +AC_SUBST([plugindir]) + +localedir="$datarootdir/locale" +AC_SUBST([localedir]) + +dnl Reliably #include "config.h" (for large file support) +dnl ===================================================== +CPPFLAGS="$CPPFLAGS -include config.h" + + +### --------------------------------------------------------------------------- +dnl Output configuration files +dnl ========================== +define(GENERATED_FILES, + audacious.pc + buildsys.mk + extra.mk + man/audtool.1 + man/audacious.1 + src/libaudcore/audio.h + win32/audacious.nsi + win32/override/README.txt) + +[GENERATED_FILES]="m4_normalize(GENERATED_FILES)" +AC_SUBST([GENERATED_FILES]) + +AC_CONFIG_FILES(GENERATED_FILES) +AC_OUTPUT + +### --------------------------------------------------------------------------- +dnl Print out the results +dnl ===================== +echo "" +echo "Configuration:" +echo "" +echo " Install path: $prefix" +echo "" +echo " D-Bus support: $USE_DBUS" +echo " GTK+ support: $USE_GTK" +echo " Qt support: $USE_QT" +echo " Valgrind analysis support: $enable_valgrind" +echo "" diff --git a/contrib/audacious.appdata.xml b/contrib/audacious.appdata.xml new file mode 100644 index 0000000..a10d9d0 --- /dev/null +++ b/contrib/audacious.appdata.xml @@ -0,0 +1,31 @@ + + + + audacious.desktop + CC0-1.0 + BSD-2-Clause + Audacious + Lightweight audio player + +

+ Audacious is an open source audio player. Originally a descendant of XMMS, + Audacious plays your music how you want it, without stealing away your + computer’s resources from other tasks. +

+

+ Drag and drop folders and individual song files, search for artists and + albums in your entire music library, or create and edit your own custom + playlists. Listen to CD’s or stream music from the Internet. Tweak the + sound with the graphical equalizer or experiment with LADSPA + effects. Enjoy the modern GTK-themed interface or change things up with + Winamp Classic skins. Use the plugins included with Audacious to fetch + lyrics for your music, to set an alarm in the morning, and more. +

+
+ https://audacious-media-player.org + + https://audacious-media-player.org/images/gtk-interface.png + https://audacious-media-player.org/images/winamp-interface.png + https://audacious-media-player.org/images/settings-window.png + +
diff --git a/contrib/macpack/Audacious.app/Contents/Info.plist b/contrib/macpack/Audacious.app/Contents/Info.plist new file mode 100644 index 0000000..77e2fbd --- /dev/null +++ b/contrib/macpack/Audacious.app/Contents/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleName + Audacious + CFBundleIdentifier + org.audacious-media-player + CFBundleDisplayName + Audacious + CFBundleIconFile + Audacious + CFBundleVersion + 3.11.0 + CFBundlePackageType + APPL + CFBundleSignature + Auda + CFBundleExecutable + audacious + LSMultipleInstancesProhibited + + NSHighResolutionCapable + + NSHighResolutionMagnifyAllowed + + NSHumanReadableCopyright + Copyright © 2001-2018 Audacious developers and others + + diff --git a/contrib/macpack/Audacious.app/Contents/MacOS/audacious b/contrib/macpack/Audacious.app/Contents/MacOS/audacious new file mode 120000 index 0000000..16ec655 --- /dev/null +++ b/contrib/macpack/Audacious.app/Contents/MacOS/audacious @@ -0,0 +1 @@ +/usr/local/bin/audacious \ No newline at end of file diff --git a/contrib/macpack/Audacious.app/Contents/PkgInfo b/contrib/macpack/Audacious.app/Contents/PkgInfo new file mode 100644 index 0000000..7b9a4f2 --- /dev/null +++ b/contrib/macpack/Audacious.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPLAuda \ No newline at end of file diff --git a/contrib/macpack/Audacious.app/Contents/Resources/Audacious.icns b/contrib/macpack/Audacious.app/Contents/Resources/Audacious.icns new file mode 100644 index 0000000..090afb8 Binary files /dev/null and b/contrib/macpack/Audacious.app/Contents/Resources/Audacious.icns differ diff --git a/contrib/thunar-sendto-audacious-playlist.desktop b/contrib/thunar-sendto-audacious-playlist.desktop new file mode 100644 index 0000000..a01c09a --- /dev/null +++ b/contrib/thunar-sendto-audacious-playlist.desktop @@ -0,0 +1,19 @@ +[Desktop Entry] +Version=1.0 + +Type=Application + +Name=Audacious Playlist +Name[de]=Audacious Wiedergabeliste +Name[fr]=Liste de lecture d'Audacious +GenericName=Audio Playlist +GenericName[de]=Musik Wiedergabeliste +GenericName[fr]=Liste de lecture de musique +Comment=Enqueue files to playlist +Comment[de]=Dateien zur Wiedergabeliste hinzufügen +Comment[fr]=Ajouter à la liste de lecture +Icon=sound + +Exec=audacious -e %F +Terminal=false +MimeType=application/ogg;application/x-cue;application/x-ogg;application/xspf+xml;audio/midi;audio/mp3;audio/mpeg;audio/mpegurl;audio/ogg;audio/prs.sid;audio/x-flac;audio/x-it;audio/x-mod;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-wma;audio/x-musepack;audio/x-s3m;audio/x-scpls;audio/x-stm;audio/x-vorbis+ogg;audio/x-wav;audio/x-xm;x-content/audio-cdda;x-directory/normal;inode/directory; diff --git a/contrib/xchat-audacious.py b/contrib/xchat-audacious.py new file mode 100644 index 0000000..d748c96 --- /dev/null +++ b/contrib/xchat-audacious.py @@ -0,0 +1,125 @@ +# +# X-Chat Audacious for Audacious 1.4 and later +# This uses the native Audacious D-Bus interface. +# +# To consider later: +# - support org.freedesktop.MediaPlayer (MPRIS)? +# +# This script is in the public domain. +# $Id: xchat-audacious.py 4574 2007-05-16 07:46:17Z deitarion $ +# + +__module_name__ = "xchat-audacious" +__module_version__ = "1.0.1" +__module_description__ = "Get NP information from Audacious" + +from dbus import Bus, DBusException +import xchat + +# connect to DBus +bus = Bus(Bus.TYPE_SESSION) + +def get_aud(): + try: + return bus.get_object('org.atheme.audacious', '/org/atheme/audacious') + except DBusException: + print "\x02Either Audacious is not running or you have something wrong with your D-Bus setup." + return None + +def command_np(word, word_eol, userdata): + aud = get_aud() + if aud: + pos = aud.Position() + + length = aud.SongLength(pos) + length = (length > 0) and ("%d:%02d" % (length / 60, length % 60)) or "stream" + + playSecs = aud.Time() / 1000 + xchat.command("SAY [%s | %d:%02d/%s]" % ( + aud.SongTitle(pos).encode("utf8"), + playSecs / 60, playSecs % 60, length)) + return xchat.EAT_ALL + +def makeVoidCommand(cmd): + def callback(word, word_eol, userdata): + getattr(get_aud(), cmd, lambda: None)() + return xchat.EAT_ALL + return callback + +def command_send(word, word_eol, userdata): + if len(word) < 2: + print "You must provide a user to send the track to." + return xchat.EAT_ALL + + aud = get_aud() + if aud: + xchat.command('DCC SEND %s "%s"' % (word[1], aud.SongFilename(aud.Position()).encode("utf8"))) + return xchat.EAT_ALL + +xchat.hook_command("NP", command_np, help="Displays current playing song.") +xchat.hook_command("NEXT", makeVoidCommand('Advance'), help="Advances in Audacious' playlist.") +xchat.hook_command("PREV", makeVoidCommand('Reverse'), help="Goes backwards in Audacious' playlist.") +xchat.hook_command("PAUSE", makeVoidCommand('Pause'), help="Toggles paused status.") +xchat.hook_command("STOP", makeVoidCommand('Stop'), help="Stops playback.") +xchat.hook_command("PLAY", makeVoidCommand('Play'), help="Begins playback.") +xchat.hook_command("SENDTRACK", command_send, help="Syntax: /SENDTRACK \nSends the currently playing track to a user.") + +# IRC+PP support section + +# XChat is lame and does not give us a server list. +def get_servers(): + chanlist = xchat.get_list("channels") + servlist = [] + + for i in chanlist: + if i.server not in servlist: + servlist.append(i.server) + + return servlist + +ignore_services = 0; +def ignore_service_errors_cb(word, word_eol, userdata): + global ignore_services + + if ignore_services == 1: + return xchat.EAT_ALL + + return xchat.EAT_NONE + +#xchat.hook_print("Notice", ignore_service_errors_cb) + +def unset_ignore_services(userdata=None): + global ignore_services + + ignore_services = 0 + return 1 + +last_title = None + +def presence_notification_dispatch(userdata=None): + global ignore_services, last_title + + aud = get_aud() + + ignore_services = 1 + if aud: + pos = aud.Position() + + title = aud.SongTitle(pos).encode("utf8") + + if title != last_title: + slist = get_servers() + for i in slist: + ctx = xchat.find_context(i) + + ctx.command("nickserv set qproperty np %s" % (title)) + + last_title = title + + return 1 + +#presence_notification_dispatch() +#xchat.hook_timer(3000, presence_notification_dispatch) +#xchat.hook_timer(500, unset_ignore_services) + +print "xchat-audacious $Id: xchat-audacious.py 4574 2007-05-16 07:46:17Z deitarion $ loaded" diff --git a/extra.mk.in b/extra.mk.in new file mode 100644 index 0000000..648a7d5 --- /dev/null +++ b/extra.mk.in @@ -0,0 +1,21 @@ +GENERATED_FILES ?= @GENERATED_FILES@ +HAVE_MSWINDOWS ?= @HAVE_MSWINDOWS@ +USE_DBUS ?= @USE_DBUS@ +USE_GTK ?= @USE_GTK@ +USE_QT ?= @USE_QT@ + +pkgconfigdir = @pkgconfigdir@ + +GIO_CFLAGS ?= @GIO_CFLAGS@ +GIO_LIBS ?= @GIO_LIBS@ +GLIB_CFLAGS ?= @GLIB_CFLAGS@ +GLIB_LIBS ?= @GLIB_LIBS@ +GMODULE_CFLAGS ?= @GMODULE_CFLAGS@ +GMODULE_LIBS ?= @GMODULE_LIBS@ +GTK_CFLAGS ?= @GTK_CFLAGS@ +GTK_LIBS ?= @GTK_LIBS@ +QTCORE_CFLAGS ?= @QTCORE_CFLAGS@ +QTCORE_LIBS ?= @QTCORE_LIBS@ +QT_CFLAGS ?= @QT_CFLAGS@ +QT_LIBS ?= @QT_LIBS@ +QT_BINPATH ?= @QTBINPATH@ diff --git a/images/Makefile b/images/Makefile new file mode 100644 index 0000000..a4882ef --- /dev/null +++ b/images/Makefile @@ -0,0 +1,11 @@ +include ../buildsys.mk + +install-extra: + ${MKDIR_P} ${DESTDIR}${datarootdir}/icons/hicolor/48x48/apps + ${MKDIR_P} ${DESTDIR}${datarootdir}/icons/hicolor/scalable/apps + ${INSTALL} -m 644 audacious.png "${DESTDIR}${datarootdir}/icons/hicolor/48x48/apps/audacious.png" + ${INSTALL} -m 644 audacious.svg "${DESTDIR}${datarootdir}/icons/hicolor/scalable/apps/audacious.svg" + +uninstall-extra: + if test -f "${DESTDIR}${datarootdir}/icons/hicolor/48x48/apps/audacious.png" ; then ${RM} "${DESTDIR}${datarootdir}/icons/hicolor/48x48/apps/audacious.png" ; fi + if test -f "${DESTDIR}${datarootdir}/icons/hicolor/scalable/apps/audacious.svg" ; then ${RM} "${DESTDIR}${datarootdir}/icons/hicolor/scalable/apps/audacious.svg" ; fi diff --git a/images/README-svg b/images/README-svg new file mode 100644 index 0000000..4cda348 --- /dev/null +++ b/images/README-svg @@ -0,0 +1,19 @@ +These SVG files have been un-optimized to work around the following librsvg bug: + https://bugzilla.gnome.org/show_bug.cgi?id=620923 + +Basically, older versions of librsvg can't parse an optimized path like +".123.456", they need it spelled out as "0.123 0.456". + +An SVG file can be un-optimized by the following regex replacements: + +Replace once: + ([^0-9])\. + \10\. + +Replace until no longer found: + ([0-9]+)\.([0-9]+)\.([0-9|\.|-]+) + \1\.\2 0\.\3 + +Replace once: + www0 + www diff --git a/images/about-logo.svg b/images/about-logo.svg new file mode 100644 index 0000000..a3d3dda --- /dev/null +++ b/images/about-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/application-exit.svg b/images/application-exit.svg new file mode 100644 index 0000000..29ffab7 --- /dev/null +++ b/images/application-exit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/applications-graphics.svg b/images/applications-graphics.svg new file mode 100644 index 0000000..d7da760 --- /dev/null +++ b/images/applications-graphics.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/applications-internet.svg b/images/applications-internet.svg new file mode 100644 index 0000000..33fd294 --- /dev/null +++ b/images/applications-internet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/applications-system.svg b/images/applications-system.svg new file mode 100644 index 0000000..fce52ef --- /dev/null +++ b/images/applications-system.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/appointment-new.svg b/images/appointment-new.svg new file mode 100644 index 0000000..9c5390c --- /dev/null +++ b/images/appointment-new.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/audacious.ico b/images/audacious.ico new file mode 100644 index 0000000..f094610 Binary files /dev/null and b/images/audacious.ico differ diff --git a/images/audacious.png b/images/audacious.png new file mode 100644 index 0000000..cee9cc3 Binary files /dev/null and b/images/audacious.png differ diff --git a/images/audacious.svg b/images/audacious.svg new file mode 100644 index 0000000..4951a6e --- /dev/null +++ b/images/audacious.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/audio-card.svg b/images/audio-card.svg new file mode 100644 index 0000000..7d19bad --- /dev/null +++ b/images/audio-card.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/audio-volume-high.svg b/images/audio-volume-high.svg new file mode 100644 index 0000000..4eb32fd --- /dev/null +++ b/images/audio-volume-high.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/audio-volume-low.svg b/images/audio-volume-low.svg new file mode 100644 index 0000000..ec1f44d --- /dev/null +++ b/images/audio-volume-low.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/audio-volume-medium.svg b/images/audio-volume-medium.svg new file mode 100644 index 0000000..03eed1f --- /dev/null +++ b/images/audio-volume-medium.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/audio-volume-muted.svg b/images/audio-volume-muted.svg new file mode 100644 index 0000000..ac33bdf --- /dev/null +++ b/images/audio-volume-muted.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/audio-x-generic.svg b/images/audio-x-generic.svg new file mode 100644 index 0000000..c85e674 --- /dev/null +++ b/images/audio-x-generic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/dialog-error.svg b/images/dialog-error.svg new file mode 100644 index 0000000..4d6467d --- /dev/null +++ b/images/dialog-error.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/dialog-information.svg b/images/dialog-information.svg new file mode 100644 index 0000000..71df13f --- /dev/null +++ b/images/dialog-information.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/dialog-question.svg b/images/dialog-question.svg new file mode 100644 index 0000000..749ef63 --- /dev/null +++ b/images/dialog-question.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/dialog-warning.svg b/images/dialog-warning.svg new file mode 100644 index 0000000..ba1bb83 --- /dev/null +++ b/images/dialog-warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/document-new.svg b/images/document-new.svg new file mode 100644 index 0000000..d9d9fbc --- /dev/null +++ b/images/document-new.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/document-open-recent.svg b/images/document-open-recent.svg new file mode 100644 index 0000000..a2fcb23 --- /dev/null +++ b/images/document-open-recent.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/document-open.svg b/images/document-open.svg new file mode 100644 index 0000000..bbc81b5 --- /dev/null +++ b/images/document-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/document-save.svg b/images/document-save.svg new file mode 100644 index 0000000..5f5ce5d --- /dev/null +++ b/images/document-save.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/edit-clear.svg b/images/edit-clear.svg new file mode 100644 index 0000000..f582873 --- /dev/null +++ b/images/edit-clear.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/edit-copy.svg b/images/edit-copy.svg new file mode 100644 index 0000000..05fc194 --- /dev/null +++ b/images/edit-copy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/edit-cut.svg b/images/edit-cut.svg new file mode 100644 index 0000000..33ab7c2 --- /dev/null +++ b/images/edit-cut.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/edit-delete.svg b/images/edit-delete.svg new file mode 100644 index 0000000..4535069 --- /dev/null +++ b/images/edit-delete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/edit-find.svg b/images/edit-find.svg new file mode 100644 index 0000000..02a68a2 --- /dev/null +++ b/images/edit-find.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/edit-paste.svg b/images/edit-paste.svg new file mode 100644 index 0000000..5857a74 --- /dev/null +++ b/images/edit-paste.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/edit-select-all.svg b/images/edit-select-all.svg new file mode 100644 index 0000000..7e26120 --- /dev/null +++ b/images/edit-select-all.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/face-smile.svg b/images/face-smile.svg new file mode 100644 index 0000000..e49c792 --- /dev/null +++ b/images/face-smile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/folder-remote.svg b/images/folder-remote.svg new file mode 100644 index 0000000..ff3dccf --- /dev/null +++ b/images/folder-remote.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/folder.svg b/images/folder.svg new file mode 100644 index 0000000..a05118d --- /dev/null +++ b/images/folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/go-down.svg b/images/go-down.svg new file mode 100644 index 0000000..9eb6700 --- /dev/null +++ b/images/go-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/go-jump.svg b/images/go-jump.svg new file mode 100644 index 0000000..3173772 --- /dev/null +++ b/images/go-jump.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/go-next.svg b/images/go-next.svg new file mode 100644 index 0000000..dbf6a2c --- /dev/null +++ b/images/go-next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/go-previous.svg b/images/go-previous.svg new file mode 100644 index 0000000..b027aec --- /dev/null +++ b/images/go-previous.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/go-up.svg b/images/go-up.svg new file mode 100644 index 0000000..b36eef2 --- /dev/null +++ b/images/go-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/help-about.svg b/images/help-about.svg new file mode 100644 index 0000000..91c078a --- /dev/null +++ b/images/help-about.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/insert-text.svg b/images/insert-text.svg new file mode 100644 index 0000000..37a1852 --- /dev/null +++ b/images/insert-text.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/list-add.svg b/images/list-add.svg new file mode 100644 index 0000000..bbce967 --- /dev/null +++ b/images/list-add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/list-remove.svg b/images/list-remove.svg new file mode 100644 index 0000000..d95c793 --- /dev/null +++ b/images/list-remove.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/media-optical.svg b/images/media-optical.svg new file mode 100644 index 0000000..4e6505e --- /dev/null +++ b/images/media-optical.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/media-playback-pause.svg b/images/media-playback-pause.svg new file mode 100644 index 0000000..b1f9a01 --- /dev/null +++ b/images/media-playback-pause.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/media-playback-start.svg b/images/media-playback-start.svg new file mode 100644 index 0000000..e4442c4 --- /dev/null +++ b/images/media-playback-start.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/media-playback-stop.svg b/images/media-playback-stop.svg new file mode 100644 index 0000000..d5b9d9d --- /dev/null +++ b/images/media-playback-stop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/media-playlist-repeat.svg b/images/media-playlist-repeat.svg new file mode 100644 index 0000000..f0d3992 --- /dev/null +++ b/images/media-playlist-repeat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/media-playlist-shuffle.svg b/images/media-playlist-shuffle.svg new file mode 100644 index 0000000..31e0100 --- /dev/null +++ b/images/media-playlist-shuffle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/media-record.svg b/images/media-record.svg new file mode 100644 index 0000000..99f4158 --- /dev/null +++ b/images/media-record.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/media-skip-backward.svg b/images/media-skip-backward.svg new file mode 100644 index 0000000..53cb740 --- /dev/null +++ b/images/media-skip-backward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/media-skip-forward.svg b/images/media-skip-forward.svg new file mode 100644 index 0000000..cafa153 --- /dev/null +++ b/images/media-skip-forward.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/meson.build b/images/meson.build new file mode 100644 index 0000000..3076150 --- /dev/null +++ b/images/meson.build @@ -0,0 +1,2 @@ +install_data('audacious.png', install_dir: install_unscalable_iconpath) +install_data('audacious.svg', install_dir: install_scalable_iconpath) diff --git a/images/multimedia-volume-control.svg b/images/multimedia-volume-control.svg new file mode 100644 index 0000000..6e96278 --- /dev/null +++ b/images/multimedia-volume-control.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/preferences-desktop-font.svg b/images/preferences-desktop-font.svg new file mode 100644 index 0000000..7a92811 --- /dev/null +++ b/images/preferences-desktop-font.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/preferences-system.svg b/images/preferences-system.svg new file mode 100644 index 0000000..8965825 --- /dev/null +++ b/images/preferences-system.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/process-stop.svg b/images/process-stop.svg new file mode 100644 index 0000000..e2415ed --- /dev/null +++ b/images/process-stop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/system-run.svg b/images/system-run.svg new file mode 100644 index 0000000..611169d --- /dev/null +++ b/images/system-run.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/text-x-generic.svg b/images/text-x-generic.svg new file mode 100644 index 0000000..2459a41 --- /dev/null +++ b/images/text-x-generic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/user-desktop.svg b/images/user-desktop.svg new file mode 100644 index 0000000..898963a --- /dev/null +++ b/images/user-desktop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/user-home.svg b/images/user-home.svg new file mode 100644 index 0000000..7f94d61 --- /dev/null +++ b/images/user-home.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/user-trash.svg b/images/user-trash.svg new file mode 100644 index 0000000..7c3cf22 --- /dev/null +++ b/images/user-trash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/view-refresh.svg b/images/view-refresh.svg new file mode 100644 index 0000000..65cdc39 --- /dev/null +++ b/images/view-refresh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/view-sort-ascending.svg b/images/view-sort-ascending.svg new file mode 100644 index 0000000..f041e7d --- /dev/null +++ b/images/view-sort-ascending.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/view-sort-descending.svg b/images/view-sort-descending.svg new file mode 100644 index 0000000..488c65e --- /dev/null +++ b/images/view-sort-descending.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/window-close.svg b/images/window-close.svg new file mode 100644 index 0000000..5a6f04e --- /dev/null +++ b/images/window-close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/m4/buildsys.m4 b/m4/buildsys.m4 new file mode 100644 index 0000000..b63a58f --- /dev/null +++ b/m4/buildsys.m4 @@ -0,0 +1,263 @@ +dnl +dnl Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017 +dnl Jonathan Schleifer +dnl +dnl https://heap.zone/git/?p=buildsys.git +dnl +dnl Permission to use, copy, modify, and/or distribute this software for any +dnl purpose with or without fee is hereby granted, provided that the above +dnl copyright notice and this permission notice is present in all copies. +dnl +dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +dnl AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +dnl ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +dnl LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +dnl POSSIBILITY OF SUCH DAMAGE. +dnl + +AC_DEFUN([BUILDSYS_INIT], [ + AC_CONFIG_COMMANDS_PRE([ + AC_SUBST(CC_DEPENDS, $GCC) + AC_SUBST(CXX_DEPENDS, $GXX) + AC_SUBST(OBJC_DEPENDS, $GOBJC) + AC_SUBST(OBJCXX_DEPENDS, $GOBJCXX) + + AC_PATH_PROG(TPUT, tput) + + AS_IF([test x"$TPUT" != x""], [ + if x=$($TPUT el 2>/dev/null); then + AC_SUBST(TERM_EL, "$x") + else + AC_SUBST(TERM_EL, "$($TPUT ce 2>/dev/null)") + fi + + if x=$($TPUT sgr0 2>/dev/null); then + AC_SUBST(TERM_SGR0, "$x") + else + AC_SUBST(TERM_SGR0, "$($TPUT me 2>/dev/null)") + fi + + if x=$($TPUT bold 2>/dev/null); then + AC_SUBST(TERM_BOLD, "$x") + else + AC_SUBST(TERM_BOLD, "$($TPUT md 2>/dev/null)") + fi + + if x=$($TPUT setaf 1 2>/dev/null); then + AC_SUBST(TERM_SETAF1, "$x") + AC_SUBST(TERM_SETAF2, + "$($TPUT setaf 2 2>/dev/null)") + AC_SUBST(TERM_SETAF3, + "$($TPUT setaf 3 2>/dev/null)") + AC_SUBST(TERM_SETAF4, + "$($TPUT setaf 4 2>/dev/null)") + AC_SUBST(TERM_SETAF6, + "$($TPUT setaf 6 2>/dev/null)") + dnl OpenBSD seems to want 3 parameters for terminals + dnl ending in -256color, but the additional two + dnl parameters don't seem to do anything, so we set + dnl them to 0. + elif x=$($TPUT setaf 1 0 0 2>/dev/null); then + AC_SUBST(TERM_SETAF1, "$x") + AC_SUBST(TERM_SETAF2, + "$($TPUT setaf 2 0 0 2>/dev/null)") + AC_SUBST(TERM_SETAF3, + "$($TPUT setaf 3 0 0 2>/dev/null)") + AC_SUBST(TERM_SETAF4, + "$($TPUT setaf 4 0 0 2>/dev/null)") + AC_SUBST(TERM_SETAF6, + "$($TPUT setaf 6 0 0 2>/dev/null)") + else + AC_SUBST(TERM_SETAF1, + "$($TPUT AF 1 2>/dev/null)") + AC_SUBST(TERM_SETAF2, + "$($TPUT AF 2 2>/dev/null)") + AC_SUBST(TERM_SETAF3, + "$($TPUT AF 3 2>/dev/null)") + AC_SUBST(TERM_SETAF4, + "$($TPUT AF 4 2>/dev/null)") + AC_SUBST(TERM_SETAF6, + "$($TPUT AF 6 2>/dev/null)") + fi + ], [ + AC_SUBST(TERM_EL, '\033\133K') + AC_SUBST(TERM_SGR0, '\033\133m') + AC_SUBST(TERM_BOLD, '\033\1331m') + AC_SUBST(TERM_SETAF1, '\033\13331m') + AC_SUBST(TERM_SETAF2, '\033\13332m') + AC_SUBST(TERM_SETAF3, '\033\13333m') + AC_SUBST(TERM_SETAF4, '\033\13334m') + AC_SUBST(TERM_SETAF6, '\033\13336m') + ]) + ]) +]) + +AC_DEFUN([BUILDSYS_PROG_IMPLIB], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_MSG_CHECKING(whether we need an implib) + case "$host_os" in + cygwin* | mingw*) + AC_MSG_RESULT(yes) + PROG_IMPLIB_NEEDED='yes' + PROG_IMPLIB_LDFLAGS='-Wl,--export-all-symbols,--out-implib,lib${PROG}.a' + ;; + *) + AC_MSG_RESULT(no) + PROG_IMPLIB_NEEDED='no' + PROG_IMPLIB_LDFLAGS='' + ;; + esac + + AC_SUBST(PROG_IMPLIB_NEEDED) + AC_SUBST(PROG_IMPLIB_LDFLAGS) +]) + +AC_DEFUN([BUILDSYS_SHARED_LIB], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_MSG_CHECKING(for shared library system) + case "$host_os" in + darwin*) + AC_MSG_RESULT(Darwin) + LIB_CFLAGS='-fPIC -DPIC' + LIB_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}' + LIB_LDFLAGS_INSTALL_NAME='-Wl,-install_name,${libdir}/$${out%.dylib}.${LIB_MAJOR}.dylib' + LIB_PREFIX='lib' + LIB_SUFFIX='.dylib' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CFLAGS='-fPIC -DPIC' + PLUGIN_LDFLAGS='-bundle -undefined dynamic_lookup' + PLUGIN_SUFFIX='.bundle' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib' + CLEAN_LIB='' + ;; + mingw* | cygwin*) + AC_MSG_RESULT(MinGW / Cygwin) + LIB_CFLAGS='' + LIB_LDFLAGS='-shared -Wl,--export-all-symbols,--out-implib,${SHARED_LIB}.a' + LIB_LDFLAGS_INSTALL_NAME='' + LIB_PREFIX='lib' + LIB_SUFFIX='.dll' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CFLAGS='' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.dll' + INSTALL_LIB='&& ${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i && ${INSTALL} -m 755 $$i.a ${DESTDIR}${libdir}/$$i.a' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/$$i.a' + CLEAN_LIB='${SHARED_LIB}.a' + ;; + openbsd* | mirbsd*) + AC_MSG_RESULT(OpenBSD) + LIB_CFLAGS='-fPIC -DPIC' + LIB_LDFLAGS='-shared' + LIB_LDFLAGS_INSTALL_NAME='' + LIB_PREFIX='lib' + LIB_SUFFIX='.so.${LIB_MAJOR}.${LIB_MINOR}' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CFLAGS='-fPIC -DPIC' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.so' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i' + CLEAN_LIB='' + ;; + solaris*) + AC_MSG_RESULT(Solaris) + LIB_CFLAGS='-fPIC -DPIC' + LIB_LDFLAGS='-shared -Wl,-soname=${SHARED_LIB}.${LIB_MAJOR}.${LIB_MINOR}' + LIB_LDFLAGS_INSTALL_NAME='' + LIB_PREFIX='lib' + LIB_SUFFIX='.so' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CFLAGS='-fPIC -DPIC' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.so' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR} && rm -f ${DESTDIR}${libdir}/$$i && ${LN_S} $$i.${LIB_MAJOR}.${LIB_MINOR} ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}' + CLEAN_LIB='' + ;; + *-android*) + AC_MSG_RESULT(Android) + LIB_CFLAGS='-fPIC -DPIC' + LIB_LDFLAGS='-shared -Wl,-soname=${SHARED_LIB}.${LIB_MAJOR}' + LIB_LDFLAGS_INSTALL_NAME='' + LIB_PREFIX='lib' + LIB_SUFFIX='.so' + LDFLAGS_RPATH='' + PLUGIN_CFLAGS='-fPIC -DPIC' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.so' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0 && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0' + CLEAN_LIB='' + ;; + *) + AC_MSG_RESULT(ELF) + LIB_CFLAGS='-fPIC -DPIC' + LIB_LDFLAGS='-shared -Wl,-soname=${SHARED_LIB}.${LIB_MAJOR}' + LIB_LDFLAGS_INSTALL_NAME='' + LIB_PREFIX='lib' + LIB_SUFFIX='.so' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CFLAGS='-fPIC -DPIC' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.so' + INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0 && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0' + CLEAN_LIB='' + ;; + esac + + AC_SUBST(LIB_CFLAGS) + AC_SUBST(LIB_LDFLAGS) + AC_SUBST(LIB_LDFLAGS_INSTALL_NAME) + AC_SUBST(LIB_PREFIX) + AC_SUBST(LIB_SUFFIX) + AC_SUBST(LDFLAGS_RPATH) + AC_SUBST(PLUGIN_CFLAGS) + AC_SUBST(PLUGIN_LDFLAGS) + AC_SUBST(PLUGIN_SUFFIX) + AC_SUBST(INSTALL_LIB) + AC_SUBST(UNINSTALL_LIB) + AC_SUBST(CLEAN_LIB) +]) + +AC_DEFUN([BUILDSYS_FRAMEWORK], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([BUILDSYS_SHARED_LIB]) + + AC_CHECK_TOOL(CODESIGN, codesign) + + case "$host_os" in + darwin*) + AC_MSG_CHECKING(whether host is iOS) + AC_EGREP_CPP(yes, [ + #include + + #if (defined(TARGET_OS_IPHONE) && \ + TARGET_OS_IPHONE) || \ + (defined(TARGET_OS_SIMULATOR) && \ + TARGET_OS_SIMULATOR) + yes + #endif + ], [ + AC_MSG_RESULT(yes) + FRAMEWORK_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}' + FRAMEWORK_LDFLAGS_INSTALL_NAME='-Wl,-install_name,@executable_path/Frameworks/$$out/$${out%.framework}' + ], [ + AC_MSG_RESULT(no) + FRAMEWORK_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}' + FRAMEWORK_LDFLAGS_INSTALL_NAME='-Wl,-install_name,@executable_path/../Frameworks/$$out/$${out%.framework}' + ]) + + AC_SUBST(FRAMEWORK_LDFLAGS) + AC_SUBST(FRAMEWORK_LDFLAGS_INSTALL_NAME) + ;; + esac +]) diff --git a/man/Makefile b/man/Makefile new file mode 100644 index 0000000..82aae74 --- /dev/null +++ b/man/Makefile @@ -0,0 +1,3 @@ +MAN = audacious.1 audtool.1 + +include ../buildsys.mk diff --git a/man/audacious.1.in b/man/audacious.1.in new file mode 100644 index 0000000..aceaa51 --- /dev/null +++ b/man/audacious.1.in @@ -0,0 +1,166 @@ +.TH AUDACIOUS "1" "May 2016" "Version @PACKAGE_VERSION@" "Audacious" + +.SH NAME +audacious \- an advanced audio player. + +.SH SYNOPSIS +.B audacious +[\fIoption\fR ...] [\fIfile\fR ...] + +.SH DESCRIPTION +Audacious is a free advanced audio player for Linux and many other +UNIX-compatible systems. It focuses on low resource usage, high audio quality, +and support for a wide range of audio formats. It was originally based on Beep +Media Player, which was in turn based on XMMS. + +.SH OPTIONS +.SS Getting help: + +.TP +.B -h, --help +Show a brief list of options. + +.SS Opening files: + +.TP +.B -e, --enqueue +Add the files on the command line to the current playlist but do not start +playback. +.TP +.B -E, --enqueue-to-temp +Add the files on the command line to the ``Now Playing'' playlist and start +playback. + +.SS Controlling playback: + +.TP +.B -p, --play +Start playback. If paused, playback will resume from the same point. If +already active and not paused, it will restart from the beginning of the song. +.TP +.B -u, --pause +Pause playback, or resume if already paused. +.TP +.B -t, --play-pause +Equivalent to \fB--pause\fR if playback is active, otherwise \fB--play\fR. +.TP +.B -s, --stop +Stop playback. +.TP +.B -r, --rew +Skip to the previous song in the playlist. +.TP +.B -f, --fwd +Skip to the next song in the playlist. + +.SS Miscellaneous: + +.TP +.B -m, --show-main-window +Show the Audacious window if it is hidden and bring it to the top. +.TP +.B -j, --show-jump-box +Show the Jump to Song window. +.TP +.B -H, --headless +Start in command-line mode; i.e., without any graphical user interface. +.TP +.B -q, --quit-after-play +Exit as soon as playback stops, or immediately if there is nothing to play. +.TP +.B -v, --version +Print version information and exit. +.TP +.B -V, --verbose +Print debugging output while running (may be used twice for even more output). +.TP +.B -N, --new-instance +Starts a new instance. The second instance started may be controlled with +\fBaudtool -2\fR, the third with \fBaudtool -3\fR, etc. (up to 9 instances). + +.SH KEYBINDINGS +.ta 24 +Control + Return Play +.br +Space, Control + , Pause +.br +Control + . Stop +.br +Alt + Up Previous song +.br +Alt + Down Next song +.br +Right arrow Seek forward (by default 5 seconds) +.br +Left arrow Seek backward (by default 5 seconds) +.br +Escape Scroll to current song +.br +Control + a Select all songs in playlist +.br +Shift + Control + a Cancel selection +.br +Control + + (plus) Increase volume 5 percent +.br +Control + - (minus) Decrease volume 5 percent +.br +Control + s Toggle shuffle +.br +Control + r Toggle repeat +.br +Control + n Toggle advancing in playlist +.br +Control + m Toggle stopping after current song +.br +Control + e Display Equalizer +.br +Control + y Display Search Tool +.br +Control + i Display Song Information dialog +.br +Control + k Display Jump to Time dialog +.br +Control + j Display Jump to Song dialog +.br +Control + p Display Playlist Manager dialog +.br +Control + u Display Queue Manager dialog +.br +Control + o Display Open Files dialog +.br +Shift + Control + o Display Add Files dialog +.br +Control + l Display Open URL dialog +.br +Shift + Control + l Display Add URL dialog + +.SH FILES + +.TP +~/.config/audacious/config, ~/.config/audacious-2/config, etc. +Configuration file for each Audacious instance. +.TP +~/.config/audacious/playlists, ~/.config/audacious-2/playlists, etc. +Folders in which playlists are stored. +.TP +~/.local/share/audacious/Skins, @datarootdir@/audacious/Skins +Default locations where Audacious should look for skin files. + +.SH ENVIRONMENT + +.TP 12 +.B SKINSDIR +Colon separated list of paths where Audacious should look for skin files. +.TP +.B TARCMD +Tar command supporting GNU tar style decompression. Used for +unpacking gzip and bzip2 compressed skins. Default is \fItar\fP. +.TP +.B UNZIPCMD +Command for decompressing zip files (skins). Default is \fIunzip\fP. + +.SH "SEE ALSO" +.BR audtool (1) + +.SH WEBSITE +.I https://audacious-media-player.org diff --git a/man/audtool.1.in b/man/audtool.1.in new file mode 100644 index 0000000..45ef64c --- /dev/null +++ b/man/audtool.1.in @@ -0,0 +1,389 @@ +.TH AUDTOOL "1" "September 2017" "Version @PACKAGE_VERSION@" + +.SH NAME +.B audtool +- a small tool to control Audacious from the command line. + +.SH SYNOPSIS +.B audtool +[\fIinstance\fR] \fIcommand\fR [\fIparameter\fR ...] ... + +.SH DESCRIPTION +.B audtool +sends commands to a running instance of Audacious. +.PP +It can send many common commands, such as to skip to the next song in the +playlist, and can also print status information, such as the title of the +current song. +.PP +\fIinstance\fR may be given as \fB-1\fR, \fB-2\fR, etc. (up to \fB-9\fR) to +specify which instance of Audacious to control when multiple instances have been +started. + +.SH COMMANDS +.SS Current song information: + +.TP +.B --current-song +Print the formatted title of the current song. Depending on Audacious +settings, this may include information such as the artist and album name. To +print only the song title, use \fB--current-song-tuple-data title\fR instead. +.TP +.B --current-song-filename +Print the file name (full path or URI) of the current song. +.TP +.B --current-song-length +Print the length of the current song in M:SS format. +.TP +.B --current-song-length-seconds +Print the length of the current song in seconds. +.TP +.B --current-song-length-frames +Print the length of the current song in milliseconds. +.TP +.B --current-song-output-length +Print the playback time counter in M:SS format. +.TP +.B --current-song-output-length-seconds +Print the playback time counter in seconds. +.TP +.B --current-song-output-length-frames +Print the playback time counter in milliseconds. +.TP +.B --current-song-bitrate +Print the streaming bitrate in bits per second. +.TP +.B --current-song-bitrate-kbps +Print the streaming bitrate in kilobits per second (1 kilobit = 1000 bits). +.TP +.B --current-song-frequency +Print the sampling rate in hertz. +.TP +.B --current-song-frequency-khz +Print the sampling rate in kilohertz. +.TP +.B --current-song-channels +Print the number of audio channels. +.TP +.B --current-song-tuple-data \fIfield\fR +Print the value of a named field (\fBartist\fR, \fByear\fR, \fBgenre\fR, etc.) +for the current song. If the field name is omitted, a list of allowed fields +will be printed. +.TP +.B --current-song-info +Print the streaming bitrate, sampling rate, and number of audio channels. + +.SS Playback commands: + +.TP +.B --playback-play +Start playback. If paused, playback will resume from the same point. If +already active and not paused, it will restart from the beginning of the song. +.TP +.B --playback-pause +Pause playback, or resume if already paused. +.TP +.B --playback-playpause +Equivalent to \fB--playback-pause\fR if playback is active, otherwise +\fB--playback-play\fR. +.TP +.B --playback-stop +Stop playback. +.TP +.B --playback-playing +Return an exit code of 0 (true) if playback is active. +.TP +.B --playback-paused +Return an exit code of 0 (true) if playback is paused. +.TP +.B --playback-stopped +Return an exit code of 0 (true) if playback is not active. +.TP +.B --playback-status +Print the playback status (``playing'', ``paused'', or ``stopped''). +.TP +.B --playback-seek \fItime\fR +Seek to the given time in seconds, relative to the beginning of the song. +.TP +.B --playback-seek-relative \fItime\fR +Seek to the given time in seconds, relative to the current time counter. +.TP +.B --playback-record +Toggle recording of the output stream (using FileWriter). +.TP +.B --playback-recording +Return an exit code of 0 (true) if stream recording is enabled. + +.SS Playlist selection: + +.TP +.B --select-displayed +Specifies that any subsequent playlist commands should apply to the playlist +currently displayed by Audacious, regardless of which playlist is playing. This +setting takes effect until it is overridden by \fB--select-playing\fR or +Audacious is restarted. + +The following commands are also affected: +.RS +.RS +--current-song +.br +--current-song-filename +.br +--current-song-length[-seconds,-frames] +.br +--current-song-tuple-data +.RE +.RE +.TP +.B --select-playing +Specifies that when playback is active, any subsequent playlist commands should +apply to the playlist currently playing. When playback is stopped, the behavior +is the same as \fB--select-displayed\fR. This setting is the default. + +.SS Playlist commands: + +.TP +.B --playlist-advance +Skip to the next song in the playlist. +.TP +.B --playlist-reverse +Skip to the previous song in the playlist. +.TP +.B --playlist-addurl \fIpath\fR +Add a song to end of the playlist. Either a URI or a local file path (absolute +or relative) may be given. +.TP +.B --playlist-insurl \fIpath\fR \fIposition\fR +Insert a song at the given position (one-based) in the playlist. +.TP +.B --playlist-addurl-to-new-playlist \fIpath\fR +Add a song to the ``Now Playing'' playlist, creating the playlist if necessary, +and begin to play the song. Depending on Audacious settings, the playlist may +first be cleared. +.TP +.B --playlist-delete \fIposition\fR +Remove the song at the given position from the playlist. +.TP +.B --playlist-length +Print the number of songs in the playlist. +.TP +.B --playlist-song \fIposition\fR +Print the formatted title of a song in the playlist. +.TP +.B --playlist-song-filename \fIposition\fR +Print the file name (full path or URI) of a song in the playlist. +.TP +.B --playlist-song-length \fIposition\fR +Print the length of a song in the playlist in M:SS format. +.TP +.B --playlist-song-length-seconds \fIposition\fR +Print the length of a song in the playlist in seconds. +.TP +.B --playlist-song-length-frames \fIposition\fR +Print the length of a song in the playlist in milliseconds. +.TP +.B --playlist-tuple-data \fIfield\fR \fIposition\fR +Print the value of a named field for a song in the playlist. +.TP +.B --playlist-display +Print the titles of all the songs in the playlist. +.TP +.B --playlist-position +Print the position of the current song in the playlist. +.TP +.B --playlist-jump \fIposition\fR +Skip to the song at the given position in the playlist. +.TP +.B --playlist-clear +Clear the playlist. +.TP +.B --playlist-auto-advance-status +Print the status of playlist auto-advance (``on'' or ``off''). +.TP +.B --playlist-auto-advance-toggle +Toggle playlist auto-advance. +.TP +.B --playlist-repeat-status +Print the status of playlist repeat (``on'' or ``off''). +.TP +.B --playlist-repeat-toggle +Toggle playlist repeat. +.TP +.B --playlist-shuffle-status +Print the status of playlist shuffle (``on'' or ``off''). +.TP +.B --playlist-shuffle-toggle +Toggle playlist shuffle. +.TP +.B --playlist-stop-after-status +Print the ``stop after current song'' option (``on'' or ``off''). +.TP +.B --playlist-stop-after-toggle +Toggle the ``stop after current song'' option. + +.SS More playlist commands: + +.TP +.B --number-of-playlists +Print the number of open playlists. +.TP +.B --current-playlist +Print the number of the current playlist, where "current" is interpreted +according to \fB--select-displayed\fR or \fB--select-playing\fR. +.TP +.B --play-current-playlist +Start playback in the current playlist, resuming from the last point played if +possible. When \fB--select-displayed\fR is in effect, this command can be used +to switch playback to the displayed playlist. +.TP +.B --set-current-playlist \fIplaylist\fR +Display the given playlist. When \fB--select-playing\fR is in effect and a +different playlist is playing, this command will also switch playback to the +given playlist. The \fB--select-displayed\fR option disables this behavior. +.TP +.B --current-playlist-name +Print the title of the current playlist. +.TP +.B --set-current-playlist-name \fItitle\fR +Set the title of the current playlist. +.TP +.B --new-playlist +Insert a new playlist after the current one and switch to it as if +\fB--set-current-playlist\fR were used. +.TP +.B --delete-current-playlist +Remove the current playlist. + +.SS Playlist queue commands: + +.TP +.B --playqueue-add \fIposition\fR +Add the song at the given playlist position to the queue. +.TP +.B --playqueue-remove \fIposition\fR +Remove the song at the given playlist position from the queue. +.TP +.B --playqueue-is-queued \fIposition\fR +Return an exit code of 0 (true) if the song at the given playlist position is +in the queue. +.TP +.B --playqueue-get-queue-position \fIposition\fR +Print the queue position of the song at the given playlist position. +.TP +.B --playqueue-get-list-position \fIposition\fR +Print the playlist position of the song at the given queue position. +.TP +.B --playqueue-length +Print the number of songs in the queue. +.TP +.B --playqueue-display +Print the titles of all the songs in the queue. +.TP +.B --playqueue-clear +Clear the queue. + +.SS Volume control and equalizer: + +.TP +.B --get-volume +Print the current volume level in percent. +.TP +.B --set-volume \fIlevel\fR +Set the current volume level in percent. +.TP +.B --equalizer-activate [on|off] +Activate or deactivate the equalizer. +.TP +.B --equalizer-get +Print the equalizer settings (preamp and gain for all bands) in decibels. +.TP +.B --equalizer-set \fIpreamp\fR \fIband0\fR \fIband1\fR \fIband2\fR \fIband3\fR \fIband4\fR \fIband5\fR \fIband6\fR \fIband7\fR \fIband8\fR \fIband9\fR +Set the equalizer settings (preamp and gain for all bands) in decibels. +.TP +.B --equalizer-get-preamp +Print the equalizer pre-amplification in decibels. +.TP +.B --equalizer-set-preamp \fIpreamp\fR +Set the equalizer pre-amplification in decibels. +.TP +.B --equalizer-get-band \fIband\fR +Print the gain of the given equalizer band (0-9) in decibels. +.TP +.B --equalizer-set-band \fIband\fR \fIgain\fR +Set the gain of the given equalizer band (0-9) in decibels. + +.SS Miscellaneous: + +.TP +.B --mainwin-show [on|off] +Show or hide the Audacious window. +.TP +.B --filebrowser-show [on|off] +Show or hide the Add Files window. +.TP +.B --jumptofile-show [on|off] +Show or hide the Jump to Song window. +.TP +.B --preferences-show [on|off] +Show or hide the Settings window. +.TP +.B --about-show [on|off] +Show or hide the About window. +.TP +.B --version +Print version information. +.TP +.B --plugin-is-enabled \fIplugin\fR +Return an exit code of 0 (true) if the given plugin is enabled. The plugin is +specified using its installed filename minus the folder path and suffix: for +example, \fBcrossfade\fR for \fI@plugindir@/Effect/crossfade.so\fR. +.TP +.B --plugin-enable \fIplugin\fR [on|off] +Enable or disable the given plugin. Note that interface and output plugins +cannot be disabled directly since one of each must always be active. Enabling +an interface or output plugin will automatically disable the previous plugin. +.TP +.B --config-get [\fIsection\fR:]\fIname\fR +Print the value of a configuration setting. Any use of this command is +entirely unsupported. How to find the \fIsection\fR and \fIname\fR of a given +setting is left as an exercise for the reader. +.TP +.B --config-set [\fIsection\fR:]\fIname\fR \fIvalue\fR +Change the value of a configuration setting. This command is unsupported and +dangerous. It might have unexpected side effects (such as crashing Audacious), +or it might have no effect at all. Use it at your own risk! +.TP +.B --shutdown +Shut down Audacious. +.TP +.B --help +Print a brief summary of audtool commands. +.PP +Commands may be prefixed with `--' (GNU-style long options) or not, your choice. + +.SH BUGS + +There are no known bugs in audtool at this time; if you find any please report +them at \fIhttps://redmine.audacious-media-player.org/projects/audacious\fR. + +.SH AUTHORS + +.B audtool +was written by George Averill and Ariadne +Conill . +.PP +This manual page was written by Adam Cecile and Kiyoshi +Aman . Some additional tweaks were done by Ariadne Conill + and Tony Vroon . The manual +page was updated for Audacious 3.7 and later by John Lindgren +. +.PP +This work is licensed under a Creative Commons Attribution 3.0 Unported License +. + +.SH "SEE ALSO" +.BR audacious (1) + +.SH WEBSITE +.I https://audacious-media-player.org diff --git a/man/meson.build b/man/meson.build new file mode 100644 index 0000000..d65eca2 --- /dev/null +++ b/man/meson.build @@ -0,0 +1,9 @@ +mans = ['audtool.1', 'audacious.1'] + +foreach man : mans + configure_file(input: '@0@.in'.format(man), + output: man, + configuration: conf, + install: true, + install_dir: join_paths(get_option('mandir'), 'man1')) +endforeach diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..450277d --- /dev/null +++ b/meson.build @@ -0,0 +1,154 @@ +project('audacious', 'c', 'cpp', + version: '4.0-devel', + meson_version: '>= 0.50') + + +copyright = 'Copyright (C) 2001-2020 Audacious developers and others' + + +qt5 = import('qt5') +gnome = import('gnome') + + +glib_req = '>= 2.32' +glib_dep = dependency('glib-2.0', version: glib_req, required: true) +gmodule_dep = dependency('gmodule-2.0', version: glib_req, required: true) + + +if get_option('qt') + qt_req = '>= 5.2' + qt_dep = dependency('qt5', version: qt_req, required: true, modules: ['Core', 'Widgets', 'Gui']) +endif + + +cc = meson.get_compiler('c') +cxx = meson.get_compiler('cpp') + + +if cc.get_id() == 'gcc' or cc.get_id() == 'clang' + common_flags = [ + '-pipe', + '-ffast-math', + '-Wall', + '-Wtype-limits', + '-Wno-stringop-truncation' + ] + + cxx_flags = [ + '-Wno-non-virtual-dtor', + '-Woverloaded-virtual' + ] + + check_cflags = ['-std=gnu99'] + common_flags + check_cxxflags = ['-std=gnu++11'] + common_flags + cxx_flags + + foreach arg : check_cflags + if cc.has_argument(arg) + add_project_arguments(arg, language: 'c') + endif + endforeach + + foreach arg : check_cxxflags + if cxx.has_argument(arg) + add_project_arguments(arg, language: 'cpp') + endif + endforeach +endif + + +conf = configuration_data() +conf.set_quoted('BUILDSTAMP', '???') +conf.set_quoted('COPYRIGHT', copyright) +conf.set_quoted('PACKAGE', meson.project_name()) +conf.set_quoted('VERSION', meson.project_version()) +conf.set('PACKAGE_VERSION', meson.project_version()) +if host_machine.endian() == 'big' + conf.set10('WORDS_BIGENDIAN', true) + conf.set10('BIGENDIAN', true) +else + conf.set10('BIGENDIAN', false) +endif + + +# XXX - investigate to see if we can do better +conf.set_quoted('PLUGIN_SUFFIX', '.so') +if host_machine.system() == 'windows' + conf.set_quoted('PLUGIN_SUFFIX', '.dll') +elif host_machine.system() == 'darwin' + conf.set_quoted('PLUGIN_SUFFIX', '.dylib') +endif + + +if host_machine.system() == 'windows' + conf.set('EXPORT', '__declspec(dllexport)') + conf.set_quoted('PLUGIN_SUFFIX', '.dll') +elif cc.get_id() == 'gcc' or cc.get_id() == 'clang' + add_project_arguments('-fvisibility=hidden', language: 'c') + add_project_arguments('-fvisibility=hidden', language: 'cpp') + conf.set('EXPORT', '__attribute__((visibility("default")))') +endif + + +install_bindir = get_option('bindir') +install_datadir = join_paths(get_option('datadir'), 'audacious') +install_plugindir = join_paths(get_option('libdir'), 'audacious') +install_localedir = get_option('localedir') +install_desktoppath = join_paths(get_option('datadir'), 'applications') +install_desktopfile = join_paths(install_desktoppath, 'audacious.desktop') +install_iconpath = join_paths(get_option('datadir'), 'icons') +install_unscalable_iconpath = join_paths(install_iconpath, 'hicolor', '48x48', 'apps') +install_scalable_iconpath = join_paths(install_iconpath, 'hicolor', 'scalable', 'apps') +install_iconfile = join_paths(install_unscalable_iconpath, 'audacious.png') + + +conf.set_quoted('INSTALL_BINDIR', join_paths(get_option('prefix'), install_bindir)) +conf.set_quoted('INSTALL_DATADIR', join_paths(get_option('prefix'), install_datadir)) +conf.set_quoted('INSTALL_PLUGINDIR', join_paths(get_option('prefix'), install_plugindir)) +conf.set_quoted('INSTALL_LOCALEDIR', join_paths(get_option('prefix'), install_localedir)) +conf.set_quoted('INSTALL_DESKTOPFILE', join_paths(get_option('prefix'), install_desktopfile)) +conf.set_quoted('INSTALL_ICONFILE', join_paths(get_option('prefix'), install_iconfile)) +conf.set('plugindir', install_plugindir) +conf.set('datarootdir', get_option('datadir')) + + +if get_option('dbus') + conf.set10('USE_DBUS', true) +endif + + +if get_option('qt') + conf.set10('USE_QT', true) +endif + + +subdir('src') +subdir('po') +subdir('man') +subdir('images') + + +install_data('AUTHORS', 'COPYING') + + +install_data('audacious.desktop', install_dir: install_desktoppath) + + +pkg = import('pkgconfig') + +# When Meson fixes the utter disappointment that is +# https://github.com/mesonbuild/meson/issues/5836, +# use libaudcore_lib as base dependency here. +pkg.generate( + libraries: ['-L${libdir} -laudcore'], + variables: [ + 'plugin_dir=${libdir}/audacious', + + # Appease broken third-party plugin build systems. + 'audacious_include_dir=${includedir}', + 'include_dir=${includedir}', + 'lib_dir=${libdir}' + ], + description: 'versatile and handy multi platform media player', + name: 'audacious', + url: 'https://audacious-media-player.org' +) diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..6942ba6 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,4 @@ +option('dbus', type: 'boolean', value: true, + description: 'Whether DBus support is enabled') +option('qt', type: 'boolean', value: true, + description: 'Whether Qt support is enabled') diff --git a/mkrelease.sh b/mkrelease.sh new file mode 100755 index 0000000..4b3a556 --- /dev/null +++ b/mkrelease.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +if ! test -e .git +then + echo This script must be run in a Git repository + exit 1 +fi + +RELEASENAME=`git describe --tags` + +if test -e $RELEASENAME +then + echo $RELEASENAME already exists, not overwriting + exit 1 +fi + +echo "Exporting HEAD to $RELEASENAME ..." +git archive --format=tar --prefix=$RELEASENAME/ HEAD | tar x || exit 1 + +echo "Running autoreconf ..." +cd $RELEASENAME || exit 1 +autoreconf || exit 1 +rm -rf .gitignore .hgignore aclocal.m4 autom4te.cache + +echo "Building $RELEASENAME.tar.bz2 ..." +cd .. || exit 1 +tar cfj $RELEASENAME.tar.bz2 $RELEASENAME || exit 1 diff --git a/po/LINGUAS b/po/LINGUAS new file mode 100644 index 0000000..fe45893 --- /dev/null +++ b/po/LINGUAS @@ -0,0 +1,42 @@ +ar +be +bg +ca +cmn +cs +da +de +el +en_GB +es_AR +es_MX +es +et +fi +fr +gl +hu +id_ID +it +ja +ko +lt +lv +ml_IN +ms +nl +pl +pt_BR +pt_PT +ru +si +sk +sr +sr_RS +sv +ta +tr +uk +zh_CN +zh_TW + diff --git a/po/Makefile b/po/Makefile new file mode 100644 index 0000000..774f4d0 --- /dev/null +++ b/po/Makefile @@ -0,0 +1,66 @@ +# Short KISS instructions: +# +# - To add new languages: Add *.po target to LOCALES Make variable below +# - Update and merge .po-files: make update-po +# - Only update the template .pot-file only: make update-pot +# - Run update-potfiles.sh when any new sourcefiles with translatable strings +# have been introduced, and then continue with 'make update-po' or +# 'make update-pot' respectively. +# +LOCALES = ar.po \ + be.po \ + bg.po \ + ca.po \ + cmn.po \ + cs.po \ + da.po \ + de.po \ + el.po \ + en_GB.po \ + es_AR.po \ + es_MX.po \ + es.po \ + et.po \ + fi.po \ + fr.po \ + gl.po \ + hu.po \ + id_ID.po \ + it.po \ + ja.po \ + ko.po \ + lt.po \ + lv.po \ + ml_IN.po \ + ms.po \ + nl.po \ + pl.po \ + pt_BR.po \ + pt_PT.po \ + ru.po \ + si.po \ + sk.po \ + sr.po \ + sr_RS.po \ + sv.po \ + ta.po \ + tr.po \ + uk.po \ + zh_CN.po \ + zh_TW.po + +include ../extra.mk +include ../buildsys.mk + +POTTEMPLATE=$(PACKAGE_NAME).pot + +update-pot: + @echo Updating $(POTTEMPLATE) ... + xgettext --default-domain=$(PACKAGE_NAME) --language=C \ + --keyword=_ --keyword=N_ --from-code="utf-8" \ + --msgid-bugs-address="https://redmine.audacious-media-player.org/" \ + --directory=.. --files-from=POTFILES.in -o $(POTTEMPLATE) + +update-po: update-pot + @echo Updating .po -files ... + @for lang in $(LOCALES); do echo -n "$$lang : "; msgmerge --update "$$lang" $(POTTEMPLATE); done diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..6950361 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,49 @@ +# Please don't update this file manually - use ./update-potfiles.sh instead! +src/audacious/main.cc +src/libaudcore/adder.cc +src/libaudcore/audstrings.cc +src/libaudcore/drct.cc +src/libaudcore/output.cc +src/libaudcore/playback.cc +src/libaudcore/playlist.cc +src/libaudcore/playlist-files.cc +src/libaudcore/probe.cc +src/libaudcore/tuple.cc +src/libaudcore/vfs.cc +src/libaudcore/vfs_local.cc +src/libaudgui/about.cc +src/libaudgui/confirm.cc +src/libaudgui/eq-preset.cc +src/libaudgui/equalizer.cc +src/libaudgui/file-opener.cc +src/libaudgui/infopopup.cc +src/libaudgui/infowin.cc +src/libaudgui/jump-to-time.cc +src/libaudgui/jump-to-track.cc +src/libaudgui/playlists.cc +src/libaudgui/plugin-menu.cc +src/libaudgui/plugin-prefs.cc +src/libaudgui/plugin-view.cc +src/libaudgui/prefs-widget.cc +src/libaudgui/prefs-window.cc +src/libaudgui/preset-browser.cc +src/libaudgui/queue-manager.cc +src/libaudgui/status.cc +src/libaudgui/url-opener.cc +src/libaudgui/util.cc +src/libaudqt/about-qt.cc +src/libaudqt/audqt.cc +src/libaudqt/equalizer-qt.cc +src/libaudqt/fileopener.cc +src/libaudqt/infopopup-qt.cc +src/libaudqt/info-widget.cc +src/libaudqt/infowin-qt.cc +src/libaudqt/log-inspector.cc +src/libaudqt/playlist-management.cc +src/libaudqt/plugin-menu-qt.cc +src/libaudqt/prefs-plugin.cc +src/libaudqt/prefs-pluginlist-model.cc +src/libaudqt/prefs-window-qt.cc +src/libaudqt/queue-manager-qt.cc +src/libaudqt/url-opener-qt.cc +src/libaudqt/util-qt.cc diff --git a/po/ar.po b/po/ar.po new file mode 100644 index 0000000..87108c3 --- /dev/null +++ b/po/ar.po @@ -0,0 +1,1512 @@ +# Arabic translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# abouzakaria kov , 2016 +# Ibrahim Saed , 2012 +# Rached Noureddine , 2015,2019 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: abouzakaria kov \n" +"Language-Team: Arabic (http://www.transifex.com/audacious/audacious/language/ar/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ar\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "مساعَدة" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "نسخة الإصدار" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "شغّل" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "ألبِث" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "البِث إن مشغَّل ،أو شغِّل" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "أوْقف المشغِّّل" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "المقطوعة السّابِقة" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "المقطوعة التالية" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "أضِف مِلفّات لِقائمة التّشغيل" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "أضِف مِلفّات لِقائمة تشغيل مؤقتة" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "أظْهر النّافذة الرئِّيسية" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "الرخصة" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "إبدأ بدون واجِهة رسوميّة" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "أنه عند وقف التشغيل" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "إطْبع رسائل المعَالجة (يمكن إستخدامها مرتيين)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "خَيَار مجْهولْ: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "خَيَار مجْهولْ: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Usage: audacious [OPTION] ... [FILE] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Select instance to run/control" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "أُودَايْشسْ" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d عثر على ملف" +msgstr[1] "%d عثر على ملف" +msgstr[2] "%d عثر على ملفين" +msgstr[3] "%d عثر على ملفات" +msgstr[4] "%d عثر على ملفات" +msgstr[5] "%d عثر على ملفات" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "خطأ في القراءة %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "لم يتم العثور على الملفات." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "قائمة تشغيل جديدة" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "الإدخال القياسي" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "ضوت CD, مقطع %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(خطأ ترميز)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "يجب إعداد التسجيل في إعدادات الصوت قبل الإستخدام." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "خطأ في فتخ دفق إخراج" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "خطأ في تسجيل المخارج" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "خطأ في القراءة %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "تنسيق غير صالح" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "المُشَغّل الأن" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "خطأ فتح %s:\n %s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "خطأ تحميل %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "لا يمكن تحميل %s: إمتداد غير مدعوم." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "لا يمكن حفظ %s: إمتداد غير مدعوم." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "خطأ في تحميل المُلحَقة" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "البحث عن الخطاء" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "تنسيق الملف مجهول" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "خطأ في قراءة البيانات الوصفية" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "أحادي" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "صوت مُجَسَّم" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d قناة" +msgstr[1] "%d قناة" +msgstr[2] "%d قناتين" +msgstr[3] "%d قنوات" +msgstr[4] "%d قنوات" +msgstr[5] "%d قنوات" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "الصوت" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "مَقطْع %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(عنوان مجهول)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "مخطط URI غير معروف" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "إسم الملف غير صالح" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "وضع الوصول غير صالح" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "شُكْر" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "الرخصة" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "عنْ أودَاشِيسْ" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_إلغ" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_لا تسأل مرة أخرى" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "هل تريد إزالة بشكل دائم “%s”?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_حذف" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "إزالة قائمة التشغيل" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "ماذا تريد أن نطلق على هذا التشغيل؟" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_اعد التسمية" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "اعادة تسمية القائمة" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "ملف المعدل ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "ملف EQF..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "استيراد" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "تصدير" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "معدلات الصوت" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "حفظ المعدل" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "حذف المحدد" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "العودة عن التغييرات" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_تفعيل" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 هرتز" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 هرتز" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 هرتز" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 هرتز" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 هرتز" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 كيلوهرتز" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 كيلوهرتز" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 كيلوهرتز" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 كيلوهرتز" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 كيلوهرتز" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "مُعَدِّلْ الصّوتْ" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "معدلات ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "إعادة تعيين إلى صفر" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "مُضخّم" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "إفتح الملفات" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_افتح" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "اغلق_النافذة عند الفتح" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "أضف ملفات" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_أضف" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "اغلق _النافذة مع الاضافة" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_اخرج" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "العنوان" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "المؤدي" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "الألبوم" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "النوع" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "السَّنة" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "مَقْطع" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "المُدة" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "صِيغة:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "جودة:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "معدل البت:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "جاز" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "روك" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "محيط" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "البيبوب" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "البلوجراس" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "بلوز" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "غرفة الموسيقى" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "كلاسيكي" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "ريفي" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "معدن ثقيل" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "ديسكو" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "استماع سهل" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "قوم" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "جبان" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "راب العصابات" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "جوسبل" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "الجرونج" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "هارد روك" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "معدن ثقيل" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "هيب هوپ" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "منزل" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "جاز" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "أدغال" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "ميتال" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "عصر جديد" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "موجة جديدة" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "ضجيج" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "بوب" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "شرير الصخرة" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "راب" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "ريڭي" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "روك" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "موسيقى الروك آند رول" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "الإيقاع والبلوز" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "سكا" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "روحية" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "التأرجح" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "تكنو" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "رحلة هوب" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "حفظ بنجاح" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "حفظ الخطاء" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "معلومات المقطوعة" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "ألبوم المؤدي" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "تعليق" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "رقم المقطع" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "إحفظْ" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "التالي" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d كب/ث" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "غير متوفر" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_الانتقال السريع" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "الانتقال السريع للوقت" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "أدخل الوقت (minutes:seconds):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "صفْْ" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "لا_تصف" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "إذهب للمقطوعة" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "مُرَشِّح" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "مرشِّح" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "و_قف التنقل" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_أكتب" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "تأكيد الكتابة" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "اكتب %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "يرجى كتابة اسم ملف التمديد أو تحديد تنسيق من القائمة المنسدلة." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "حدد تنسيق من قبل التمديد" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "صدر قائمة التشغيل" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_صدر" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "استورد قائمة التشغيل" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_استيراد" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_إضافات ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "حول %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s إعدادات" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_طبق" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_اعدادات" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_حول" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "اختر ملفات" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "اختر مجلد" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "المَظْهر" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "الصوت" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "الشَّبَكة" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "قائمة التشغيل" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "الملحقات" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "متقدم" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "عامْ" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "مؤثرات" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "مرئيات" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "مدخل" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "نقل" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "ألبوم المؤدي" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "رقم المقطع" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "إسم الملف" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "مسار الملف" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "التاريخ" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "ترميز" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "جودة" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "لا شيء" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "العربية" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "البلطيق" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "الصّينِية" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "اليونان" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "العِبرية" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "اليابانية" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "الكورية" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "البولندية" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "الروسية" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "التايوانية" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "التركية" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "أوتوماتيكي" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "نقطة" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "الشفرة مفككة" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "استعد بعد القراءة" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "بعد تطبيق التأثيرات" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "بعد تطبيق معدلات الصوت" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "مبني على العشوائية" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "واجهة:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "ملحقات المخرجات" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "وسع كل الملفات:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "وسع الملفات الغير معلمة:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "إعدادات المخرجات" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "عمق البت:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "حجم المخزن المؤقت:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "م ث" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Soft clipping" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "استخدام مستوى صوت البرامج (غير مستحسن)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "إعدادات التسجيل" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "سجل دفق:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "القراءة من جديد" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "تفعيل القراءة من جديد" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Prevent clipping (مستحسن)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "اسم المضيف الوكيل:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "منفذ الوكيل:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "اسم المستخدم الوكيل:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "كلمة سر الوكيل:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "إعدادات الشبكة" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "تكوين الوكيل" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "تمكين استخدام بروكسي" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "استخدام المصادقة مع الوكيل" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Auto character encoding detector for:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Fallback character encodings:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "سلوك" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "استئناف القراءة عند بدء التشغيل" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "وقفة بدلا من الاستئناف فورا" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "تقدم عند حدف المقطوعة الحالية" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "صفر قائمة التشغيل عند فتح الملفات" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "إفتح الملفات في قائمة مؤقتة" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Song Display" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "إعرض أرقام المقطوعة" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "عرض الأصفار البادئة (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "عرض الساعات منفصلة (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "صدر" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Album Art" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "إبحث عن صور مطابقة لهذه الكلمات (comma-separated):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "إستبعد صور المطابقة لهذه الكلمات (comma-separated):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "البحث عن صور مطابقة لاسم ملف المقطوعة" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "بحث متواتر" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "عمق البحث" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "معلومات الإطار المنبثق" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "إعرض معلومات الإطار المنبثق" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "زمن الإطار المنبثق (tenths of a second):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "إعرض النطاق الزمني للمقطوعة الحالية " + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "التوافق" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpret \\ (backward slash) as a folder delimiter" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "البيانات الوصفية" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "التعريف مفقود في مسار الملف" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "لا تحمل البيانات الوصفية للمقطوعة إلى حين تشغيلها" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "بحث في محتويات الملفات المجهولة الصيغة" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "متفرقات" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "ثواني" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "العنوان" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "عنوان - المؤدي" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "عنوان - المؤدي - البوم" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "المؤدي - العنوان" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "المؤدي - الألبوم - العنوان" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "المؤدي الالبُوم المقطع. العنوان" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "المؤدي [الالبُوم] - المقطع. العنوان" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "الألبوم - العنوان" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "فئة" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "مُعدّل" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "صيغة العنوان:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "سلسلة معدلة:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "لا وجود لمساعد تسجيل الصوت متاح" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "إعدادات أودايشس" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "إلغ" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "حفظ" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "تحميل" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "تحميل ملف تعديل" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "تحميل ملف EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "خفظ ملف التعديل" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "حفظ ملفEQF " + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "مدير قوائم الانتظار" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Unqueue" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "جاري العمل..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "خطاء" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "معلومات" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "إفتح الرابط" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "أضف الرابط" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "أدخل الرابط:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "إفتح" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(تنبيهات أخرى تم إخفائها)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "إفتح المجلد" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "أضف المجلد" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "أضف" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "البيانات الوصفية" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "مُلحن" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "مُؤدّ" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "سنة التسجيل" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "تاريخ التسجيل" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "تقني" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "معدل البت" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "المستوى" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "وظيفة" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "رسالة" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "مفتش السجلات" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "صحّح" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "معلومات" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "تنبيهْ" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "مستوى السجل" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "خدمات" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "نسخ" diff --git a/po/audacious.pot b/po/audacious.pot new file mode 100644 index 0000000..4752786 --- /dev/null +++ b/po/audacious.pot @@ -0,0 +1,1484 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-03-27 19:09+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "" +msgstr[1] "" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "" + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playlist-files.cc:87 +#, c-format +msgid "Error loading %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/playlist-files.cc:161 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "" +msgstr[1] "" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "" + +#: src/libaudgui/eq-preset.cc:282 +msgid "Equalizer Presets" +msgstr "" + +#: src/libaudgui/eq-preset.cc:304 +msgid "Save Preset" +msgstr "" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "" + +#: src/libaudgui/eq-preset.cc:330 +msgid "Revert Changes" +msgstr "" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "" + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "" + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "" + +#: src/libaudgui/prefs-widget.cc:277 +msgid "Choose File" +msgstr "" + +#: src/libaudgui/prefs-widget.cc:281 +msgid "Choose Folder" +msgstr "" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "" + +#: src/libaudgui/preset-browser.cc:54 +msgid "Save" +msgstr "" + +#: src/libaudgui/preset-browser.cc:54 +msgid "Load" +msgstr "" + +#: src/libaudgui/preset-browser.cc:85 +msgid "Load Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:114 +msgid "Save Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "" + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "" diff --git a/po/be.po b/po/be.po new file mode 100644 index 0000000..6839382 --- /dev/null +++ b/po/be.po @@ -0,0 +1,1512 @@ +# Belarusian translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Aleh Mazok , 2014 +# debconf , 2014 +# dreadnote87 , 2012 +# dreadnote87 , 2012 +# Mikalai Udodau , 2012-2014,2017 +# Mikalai Udodau , 2015 +# debconf , 2014 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Mikalai Udodau \n" +"Language-Team: Belarusian (http://www.transifex.com/audacious/audacious/language/be/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: be\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Паказаць даведку па загадным радку" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Паказаць версію" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Пачаць гранне" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Прыпыніць гранне" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Прыпыніць калі грае, інакш граць" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Спыніць гранне" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Пропуск папярэдняй песні" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Пропуск наступнай песні" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Дадаць файлы да плэйлісту" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Дадаць файлы да часовага плэйлісту" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Паказаць галоўнае акно" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Паказаць акно \"Перайсці да песні\"" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Запусціць без графічнага інтэрфейсу" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Выйсці па сканчэнні грання" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Выводзіць паведамленні наладкі (можа выкарыстоўвацца двойчы)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Невядомы параметр: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Невядомы параметр: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Выкарыстанне: audacious [ПАРАМЕТР] ... [ФАЙЛ] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Выберыце асобнік для запуску/кіравання" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d файл знойдзены" +msgstr[1] "%d файлы знойдзеныя" +msgstr[2] "%d файлаў знойдзена" +msgstr[3] "%d файлаў знойдзена" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Памылка чытання %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Файлы не знойдзены." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Новы плэйліст" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Стандартны ўвод" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Audio CD, трэк %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(памылка кадавання знакаў)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Хібны фармат аўдыё" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Цяпер грае" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Памылка пры адкрыцці %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Не выйшла запусціць %s: такое пашырэнне назвы файла не падтрымліваецца." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Не выйшла захаваць %s: такое пашырэнне назвы файла не падтрымліваецца." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Памылка запуску ўбудовы" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Памылка пракручвання" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Не пазнаны фармат файла" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Памылка чытання метазвестак" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Мона" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Стэрэа" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d канал" +msgstr[1] "%d каналы" +msgstr[2] "%d каналаў" +msgstr[3] "%d каналаў" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Аўдыё CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Трэк %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(невядомая назва)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Невядомая URI-схема" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Некарэктная назва файла" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Аўтары" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Ліцэнзія" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Пра Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Скасаваць" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Больш не пытацца" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Сапраўды жадаеце назаўсёды выдаліць “%s”?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Выдаліць" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Сцерці плэйліст" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Як бы вы хацелі назваць гэты плэйліст?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Пераназваць" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Пераназваць плэйліст" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Файл прэсета ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Файл EQF ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Імпартаваць" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Экспартаваць" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Запісаць прэсет" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Сцерці прэсет" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Адкаціць змены" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Уключыць" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Гц" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "2 кГц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 кГц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 кГц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 кГц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 кГц" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Эквалайзер" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "" + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Перадузмацненне" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Адкрыць файлы" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Адкрыць" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Закрыць _акенца пры адкрыцці" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Дадаць файлы" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "Дадаць" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Закрыць _акенца пры даданні" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Закрыць" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Загаловак" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Выканаўца" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Альбом" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Жанр" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Год" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Трэк" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Даўжыня" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Фармат:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Якасць:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Бітрэйт:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Эйсід джаз" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Эйсід рок" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Эмбіент" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Біпоп" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Блюграс" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Блюз" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Камерная музыка" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Класічная музыка" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Кантры" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Дэз-метал" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Дыска" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Лёгкая Музыка" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Фолк" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Фанк" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Ганста рэп" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Евангелічныя спевы" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Гранж" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Хард-рок" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Хэві-метал" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Хіп-хоп" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "Хаўз" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Джаз" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Джангл" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Метал" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "Нью Эйдж" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "Новая хваля" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Нойз" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Поп" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Панк-рок" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Рэп" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Рэгі" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Рок" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Рок'н'ролл" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Рытм'н'блюз" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ска" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Соўл" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Свінг" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Тэхна" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Трып-хоп" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Паспяхова захавана" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Памылка захавання" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Звесткі пра песню" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Выканаўца альбома" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Каментар" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Нумар трэка" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Захаваць" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Наступны" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d Кб/с" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "Н/Д" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Перайсці" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Перайсці да часу" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Увядзіце час (мінут:секунд):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "У чаргу" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "З чаргі" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Перайсці да песні" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Фільтр: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Фільтр:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "З_акрыць пасля пераходу" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "Пера_запісаць" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Пацвердзіце перазапіс" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Перазапісаць %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Выбіраць фармат па канчатку назвы" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Экспартаваць плэйліст" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Экспарт" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Імпартаваць плэйліст" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Імпарт" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Убудовы..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Пра %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Настáўленні" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Усталяваць" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Настáўленні" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Пра праграму" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Выбраць файл" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Выбраць каталог" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Выгляд" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Аўдыё" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Сеціва" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Плэйліст" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Убудовы" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Агульныя" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Эфекты" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Візуалізацыя" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Увод" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Транспарт" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Нумар трэка" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Назва файла" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Шлях да файла" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Дата" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Кодэк" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Якасць" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Нічога" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Арабская" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Балцкая" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Кітайская (спрошчаная)" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Грэцкая" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Іўрыт" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Японская" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Карэйская" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Польская" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Расейская" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Тайваньская" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Турэцкая" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Аўтаматычна" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "З плыўной коскай" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Па дэкадаванні" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Убудова вываду:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Узмацняць усе файлы:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "дБ" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Узмацняць файлы без тэгаў:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Настáўленні вываду" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Бітавая глыбіня:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Памер буферу:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "мс" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Мяккая адсечка" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Ужываць праграмны рэгулятар гучнасці (не рэкамендуецца)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Настаўленні запісу" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Струмень запісу:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Прадухіляць адсечку (рэкамендавана)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Назва хоста проксі:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Порт проксі:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Карыстальнік проксі:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Пароль проксі:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Настáўленні сеткі" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "КіБ" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Канфігурацыя проксі" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Ужываць проксі" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Ужываць аўтэнтыфікацыю на проксі" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Аўтавызначаць кадаванне знакаў для:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Калі кадаванне не распазнана, ужыць:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Паводзіны" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Працягваць граць пры запуску" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Прыпыняць замест таго, каб адразу граць" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Пераходзіць да наступнай, калі песня выдалена" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Спустошыць плэйліст пры адкрыванні файла" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Адкрываць файлы ў часовым плэйлісце" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Паказ песні" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Паказваць нумары песень" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Вокладка альбома" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Шукаць выявы, у якіх ёсць словы (пералік праз коску):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "За выключэннем выяў, у якіх ёсць словы (пералік праз коску):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Шукаць выявы, адпаведныя назве файла з песняй" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Рэкурсіўны пошук" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Глыбіня пошуку:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Выплыўныя звесткі" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Паказваць выплыўныя паведамленні" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Затрымка паведамлення (дзясятыя долі секунды):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Паказваць часавую шкалу для дзейнай песні" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Сумяшчальнасць" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Чытаць \\ (адваротны скос) як межнік каталогу" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Метазвесткі" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Дадумваць метазвесткі з шляху файла" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Не чытаць метазвесткі, пакуль песня не зайграе" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Граць файлы з нераспазнаным пашырэннем" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "секунд" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "НАЗВА" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "НАЗВА - ВЫКАНАЎЦА" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "НАЗВА - ВЫКАНАЎЦА - АЛЬБОМ" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ВЫКАНАЎЦА - НАЗВА" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ВЫКАНАЎЦА - АЛЬБОМ - НАЗВА" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ВЫКАНАЎЦА - АЛЬБОМ - НУМАР. НАЗВА" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ВЫКАНАЎЦА [ АЛЬБОМ ] - НУМАР. НАЗВА" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "АЛЬБОМ - НАЗВА" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Катэгорыя" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Адмысловыя настáўленні" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Фармат загалоўка:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Адмысловы радок:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Плагіны для запісу гуку недаступны" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Настáўленні Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Скасаваць" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Запісаць" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Загрузіць" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Кіраўнік чаргі" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_З чаргi" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Выконваецца..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Памылка" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Інфармацыя" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Адкрыць URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Дадаць URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Увядзіце URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Адкрыць" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Далейшыя паведамленні былі прыхаваныя.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Закрыць" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Аглядаць" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Адкрыць каталог" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Дадаць каталог" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Дадаць" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Метазвесткі" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Кампазітар" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Выканаўца" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Год запісу" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Дата запісу" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Тэхнічныя" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Бітрэйт" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Узровень" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Функцыя" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Паведамленне" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Інспектар логу" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Наладка" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Інфармацыя" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Папярэджанне" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Узровень вядзення логу:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Сэрвісы" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Капіраваць" diff --git a/po/bg.po b/po/bg.po new file mode 100644 index 0000000..268b8c9 --- /dev/null +++ b/po/bg.po @@ -0,0 +1,1513 @@ +# Bulgarian translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# breaker loc , 2014 +# breaker loc , 2014 +# Ivailo Monev , 2014 +# Kiril Kirilov (Cybercop) , 2012 +# Kiril Kirilov , 2014-2015,2018 +# Myselus, 2016-2017 +# Pandi3a , 2012 +# Pandi3a , 2012 +# Георги Пацев <>, 2012 +# Радослав Иванов , 2013-2015 +# Радослав Иванов , 2013 +# Радослав Иванов , 2015-2017 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Радослав Иванов \n" +"Language-Team: Bulgarian (http://www.transifex.com/audacious/audacious/language/bg/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: bg\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Покажи помощ за работа в команден ред" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Показване на версията" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Възпроизвеждане" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Пауза" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Временно спиране, ако се възпроизвежда, в противен случай ― изпълнение" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Спиране" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Прескочи до предишната песен" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Прескочи до следващата песен" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Добавяне на файлове в списъка за възпроизвеждане" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Добавяне на файлове към временен списък" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Показване на основния прозорец" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Покажи прозореца Прескочи до песен" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Пускане без графичен интерфейс" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Изход при спиране на възпроизвеждането" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Печат на съобщения за грешка (може да се използва повторно)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Неизвестна опция: %s \n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Неизвестна опция: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Употреба: audacious [ОПЦИЯ] ... [ФАЙЛ] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Изберете инстанция за изпълнение/управление" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Намереният файл е %d" +msgstr[1] "намерени са %d файла" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Грешка при прочитане %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Няма намерени файлове." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Нов списък за възпроизвеждане" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Стандартен вход" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Аудио CD, запис %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(грешка в знаците на кодировката)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Потоковият запис трябва да бъде настроен в Звукови Настройки преди да може да се използва." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Грешка при отварянето на изходния поток" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Грешка при запис на изходения поток" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Грешка във възпроизвеждането на %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Невалиден звуков формат" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Възпроизвежда се" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Грешка при отваряне на %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Грешка при зареждането на %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "%s не може да бъде зареден: неподдържано разширение." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "%s не може да бъде запазен: неподдържано разширение." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Грешка при зареждане на разширение" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Грешка при прескачане" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Форматът на фаила на е разпознат" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Грешка при четене на мета-данни" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Моно" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Стерео" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d канал" +msgstr[1] "%d канала" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Аудио Диск" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Запис %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(неизвестно заглавие)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Неизвестна схема на Интернет адрес" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Невалидно име на файл" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Невалиден режим на достъп" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Заслуги" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Лиценз" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Относно Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Отказ" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Не питай повече" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Желаете ли окончателно да премахнете „%s“?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Премахване" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Премахни списъка за възпроизвеждане" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Как искате да именувате този списък за възпроизвеждане?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Преименуване" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Преименуване на списъка за възпроизвеждане" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Файл със заготовки..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF файл..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Внасяне" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Изнасяне" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Заготовки за тонкоректора" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Запазване на заготовка" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Изтриване на избраното" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Връщане на промените" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Активиране" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Хц" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Хц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Хц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Хц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Хц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 кХц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 кХц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 кХц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 кХц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 кХц" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Тонкоректор" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Заготовки..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Нулиране" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Предусилвател" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Отваряне на файлове" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Отвори" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Затва_ряне на прозореца при отваряне" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Добавяне на файлове" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Добави" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Затваря_не на прозореца при добавяне" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Затваряне" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Заглавие" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Изпълнител" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Албум" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Жанр" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Година" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Запис" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Продължителност" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Формат:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Качество:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Честота за бит:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Ейсид Джаз" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Ейсид Рок" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ембиънт" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Бебоп" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Блуграс" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Блус" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Чембър Мюзик" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Класика" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Кънтри" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Дет Метъл" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Диско" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Изи Листънинг" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Фолк" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Фънк" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Гангстерски Рап" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Госпел" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Грънч" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Хард Рок" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Хеви Метъл" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Хип-хоп" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "Хаус" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Джаз" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Джангъл" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Метъл" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "Ню Ейдж" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "Ню Уейв" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Нойс" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Поп" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Пънк Рок" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Рап" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Реге" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Рок" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Рокенрол" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Ритъм и блус" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ска" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Соул" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Суинг" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Техно" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Трип-хоп" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Съхраняването успешно" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Грешка при съхраняването" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Информация за песента" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr " Изпълнител на Албум" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Коментар" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Номер на записа" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Запази" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Следващ" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d кб/с" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "Няма данни" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Прескочи" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Прескачане до времева позиция" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Въвеждане на време (минути:секунди):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "На _опашка" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "П_ремахване от опашката" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Прескачане до песен" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Филтър: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Филтър:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Зат_варяне при прескачане" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "Пре_записване" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Потвърждаване на презаписване" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Да се презапише ли %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Моля въведете разширението на файла или изберете формат от падащият списък." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Изберете формат според разширението" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Изнасяне на списък за възпроизвеждане" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Изнасяне" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Внасяне на списък за възпроизвеждане" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Внасяне" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Приставки..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Относно %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Настройки" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Задай" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Настройки" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Относно" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Избор на Файл" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Избор на Папка" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Външен вид" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Аудио" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Интернет мрежа" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Списък за възпроизвеждане" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Разширения" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Разширени" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Общи" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Ефекти" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Визуализация" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Вход" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Пренасяне" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Изпълнител на албум" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Номер на запис" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Име на файла" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Път до файла" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Дата" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Кодировка" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Качество" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Без" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Арабски" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Балтийски" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Китайски" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Гръцки" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Иврит" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Японски" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Корейски" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Полски" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Руски" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Тайвански" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Турски" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Автоматично" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Плаваща запетая" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Като разкодирания" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "След прилагане на Звуково подобрение" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "След добавяне на ефекти" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "След прилагане на тонкорекция" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Базирано на разбъркване" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Интерфейс:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Приставка за изходящия поток:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Усилване на звука за всички файлове:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "дБ" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Усилване на звука на немаркираните файлове:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Настройки на изходящия поток" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Дълбочина в битове:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Размер на буфера:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "мс" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Намаляване на пращене" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Използване на програмно регулиране на силата на звука (не е препоръчително)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Настройки Запис" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Поток на запис:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "Звуково подобрение" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Активиране на Звуково подобрение" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Режим:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Предотвратяване на пращене (препоръчително)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Прокси:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Порт на прокси:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Потребителско име:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Парола:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Мрежови настройки" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "КиБ" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Настройка на прокси" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Включване на прокси" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Използване на идентифициране с прокси" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Автоматично определяне на кодировка за:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Алтернативна кодировка:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Поведение" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Продължи възпроизвеждането при стартиране" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Пауза, вместо незабавно възпроизвеждане" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Продължаване напред, ако текущата песен е премахната" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Изчистване на списъка, когато се отвори нов файл" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Отваряне на файлове във временен списък" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Показване на песен" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Показване на номера на песента" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Показване на нулите в началото (02:00 с/у 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Показване на часовете отделно (1:30:00 с/у 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Изнасяне" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Използване на алтернативни пътища, когато е възможно" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Обложка на албум" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Търсене на изображения, съдържащи тези думи (разделени със запетая):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Изключване на изображения, съдържащи тези думи (разделени със запетая):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Търсене на изображения, съдържащи името на файла" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Прогресивно търсене" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Обхват на търсенето:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Изскачаща информация" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Показване на подсказки" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Забавяне на подсказките (десети от секундата):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Покажи времетраене за текущата песен" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Съвместимост" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Знакът „\\“ да се тълкува като разделител на папките в пътя до файла" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Списък" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Рекурсивно добавяне на папки" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Добавяне на папки, включени в списъци за изпълнение" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Метаданни" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Познаване на липсващите метаданни от файловото положение" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Да не се зареждат метаданни за песните, докато се възпроизвеждат" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Проверка съдържанието на файловете с непознато разширение" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Разни" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "секунди" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "ЗАГЛАВИЕ" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "Заглавие - Изпълнител" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "Заглавие - Изпълнител - Албум" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ИЗПЪЛНИТЕЛ - ЗАГЛАВИЕ" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ИЗПЪЛНИТЕЛ - АЛБУМ - ЗАГЛАВИЕ" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ИЗПЪЛНИТЕЛ - АЛБУМ - ЗАПИС. ЗАГЛАВИЕ" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ИЗПЪЛНИТЕЛ [ АЛБУМ ] - ЗАПИС. ЗАГЛАВИЕ" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "АЛБУМ - ЗАГЛАВИЕ" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Категория" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Потребителски" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Формат на заглавие:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Потребителски низ:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Активиране на запис на звуков поток чрез %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Не е налична записваща звука приставка" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious настройки" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Отказ" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Запис" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Зареждане" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Зареждане на файл-заготовка" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Зареждане на EQF файл" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Запис на файл-заготовка" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Запис на EQF файл" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Мениджър на опашката" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Без изчакване" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Работи ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Грешка" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Информация" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Запазване в историята" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Отваряне на интернет адрес" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Добавяне на интернет адрес" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "_Изчистване на историята" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Въвеждане на интернет адрес:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Отваряне" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Допълнителните съобщения са били скрити.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Затваряне" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Намиране" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Отваряне на папка" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Добавяне на папка" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Добави" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Мета-данни" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Композитор" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Изпълнител" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Година на запис" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Дата на запис" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Технически" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Честота за бит" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Ниво" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Функция" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Съобщение" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Проверка на логовете" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Отстраняване на грешки" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Информация" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Предупреждение" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Из_чистване" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Ниво на лог:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Услуги" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Копиране" diff --git a/po/ca.po b/po/ca.po new file mode 100644 index 0000000..4bd5bd3 --- /dev/null +++ b/po/ca.po @@ -0,0 +1,1512 @@ +# Catalan translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Catalanoic , 2014,2016 +# Catalanoic , 2014 +# David Surroca Estrada , 2015-2016 +# Ernest Adrogué , 2007-2008 +# Francesc Gordillo i Cortínez , 2013 +# Francesc Gordillo i Cortínez , 2013 +# Francesc Gordillo i Cortínez , 2013 +# Jordi Amenós <>, 2011 +# Juanma Hernández , 2012 +# Juanma Hernández , 2012 +# Robert Antoni Buj Gelonch , 2016-2018 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Robert Antoni Buj Gelonch \n" +"Language-Team: Catalan (http://www.transifex.com/audacious/audacious/language/ca/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ca\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Mostra l'ajuda de la línia d'ordres" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Mostra la versió" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Inicia la reproducció" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Fes una pausa a la reproducció" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Fes una pausa, o bé reprèn la reproducció" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Atura la reproducció" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Passa a la cançó anterior" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Passa a la cançó següent" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Afegeix fitxers a la llista de reproducció" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Afegeix fitxers a una llista de reproducció temporal" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Mostra la finestra principal" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Mostra la finestra de salta a la cançó" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Inicia sense una interfície gràfica" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Surt amb l'aturada de la reproducció" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Imprimeix els missatges de depuració (pot utilitzar-se dues vegades)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Opció desconeguda: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Opció desconeguda: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Ús: audacious [OPCIÓ] ... [FITXER] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Selecciona la instància a executar o controlar" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d fitxer trobat" +msgstr[1] "%d fitxers trobats" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Error de lectura %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "No s'ha trobat cap fiter." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nova llista de reproducció" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Entrada estàndard" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "CD d'àudio, pista %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(error de codificació de caràcters)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Abans que es pugui utilitzar l'enregistrament del flux, aquest s'ha de configurar als ajusts de l'àudio." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Error en obrir el flux de sortida" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Error en l'enregistrament del flux de sortida" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Error en reproduir %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "El format d'àudio no és vàlid" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "En reproducció ara" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Error en obrir %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Error en carregar %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "No es pot carregar %s: extensió no admesa de nom de fitxer." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "No es pot desar %s: extensió no admesa de nom de fitxer." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Error en carregar el connector" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Cerca error" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Format de fitxer no reconegut" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Error en llegir les metadades" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Estèreo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d canal" +msgstr[1] "%d canals" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "CD d'àudio" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Pista %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(títol desconegut)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Esquema de l'URI no és conegut" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "El nom del fitxer no és vàlid" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Mode sense capçalera" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Crèdits" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Llicència" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Quant a Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Cancel·la" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_No tornis a preguntar-ho" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Voleu eliminar permanentment “%s”?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "Sup_rimeix" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Suprimeix la llista de reproducció" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Com voleu anomenar aquesta llista de reproducció?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Reanomena" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Reanomena la llista de reproducció" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Fitxer dels valors preestablerts..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Fitxer EQF..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importa" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exporta" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Valors preestablerts de l'equalitzador" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Desa els valors preestablerts" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Suprimeix els seleccionats" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Reverteix canvis" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Habilita" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Equalitzador" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Valors preestablerts..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Restableix a zero" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamplificador" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Obre els fitxers" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Obre" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Tanca el _diàleg en obrir" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Afegeix fitxers" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Afegeix" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Tanca el _diàleg en afegir" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Tanca" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Títol" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artista" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Àlbum" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Gènere" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Any" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Pista" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Durada" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Format:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Qualitat:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Taxa de bits:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambiental" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Música de cambra" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Clàssica" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Música lleugera" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Rock dur" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Soroll" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock & Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm & Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Tecno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Desat amb èxit" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Desa l'error" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Informació de la cançó" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Artista de l'àlbum" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Comentari" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Número de pista" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Desa" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Següent" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/D" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Salta" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Salta a l'instant" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Introduïu l'instant (minuts:segons):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Posa a la cua" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Treu de la _cua" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Salta a la cançó" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtre: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtre:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Tanca en sa_ltar" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Sobreescriu" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Confirmació de sobreescriptura" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Sobreescriure %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Si us plau, introduïu un tipus d'extensió de nom de fitxer o seleccioneu un format de la llista desplegable." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Selecciona Format per Extensió" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Exporta la llista de reproducció" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exporta" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importa la llista de reproducció" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importa" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Connectors..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Quant a %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Ajusts %s" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Configura" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "Ajust_s" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "Qu_ant a" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Triar Fitxer" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Triar Directori" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Aparença" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Àudio" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Xarxa" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Llista de reproducció" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Connectors" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Avançat" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "General" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efectes" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualització" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Entrada" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transport" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Artista de l'àlbum" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Número de pista" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nom del fitxer" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Camí del fitxer" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Data" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Còdec" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Qualitat" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Cap" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Àrab" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Bàltic" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Xinès" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Grec" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebreu" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japonès" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Coreà" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polonès" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Rus" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanès" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turc" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automàtic" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Punt flotant" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Com a descodificat" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Després d'aplicar ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Després d'aplicar els efectes" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Després d'aplicar l'equalització" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Basat en la mescla" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interfície:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Connector de sortida:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Amplifica tots els fitxers:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Amplifica els fitxers sense etiquetar:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Ajusts de la sortida" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Profunditat de mostreig:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Mida del buffer:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Retall tou" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Utilitza el control de volum de programari (no recomanat)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Ajusts de l'enregistrament" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Enregistra el flux:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Habilita ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Mode:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Evita el retall per saturació (recomanat)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Nom d'amfitrió del servidor intermediari:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Port del servidor intermediari:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Nom d'usuari:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Contrasenya:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Ajusts de la xarxa" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Configuració del servidor intermediari" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Habilita l'ús del servidor intermediari" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Autenticació al servidor intermediari" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Detecció automàtica del joc de caràcters per a:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Jocs de caràcters de reserva:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Comportament" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Reprèn la reproducció amb l'inici" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pausa en comptes de reprendre immediatament" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Avança quan s'elimina la cançó actual" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Neteja la llista de reproducció quan s'obrin fitxers" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Obre els fitxers en una llista de reproducció temporal" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Visualització de les cançons" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Mostra els números de les cançons" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Mostra els zeros a l'esquerra (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Mostra les hores per separat (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exportació" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Utilitza camins relatius quan sigui possible" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Caràtula d'àlbum" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Cerca les imatges que corresponguin amb aquestes paraules (separades per comes):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Exclou les imatges que corresponguin amb aquestes paraules (separades per comes):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Cerca les imatges que corresponguin amb el nom del fitxer de la cançó" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Cerca recursiva" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Profunditat de la cerca:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Informació emergent" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Mostra la informació emergent" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Retard del menú emergent (desenes de segon):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Mostra l'escala de temps per a la cançó actual" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Compatibilitat" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpretar \\ (barra invertida) com a delimitador de directori" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Llista de reproducció" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Afegeix carpetes de forma recursiva" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Afegeix les carpetes niades als fitxers de llista de reproducció" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadades" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Endevina les metadades que falten a partir del camí al fitxer" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "No carreguis les metadades per a les cançons fins que es reprodueixin" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Comprova el contingut dels fitxers amb l'extensió del nom del fitxer no reconeguda" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Altres" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "segons" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TÍTOL" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TÍTOL - ARTISTA" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TÍTOL - ARTISTA - ÀLBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTISTA - TÍTOL" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTISTA - ÀLBUM - TÍTOL" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTISTA - ÀLBUM - PISTA. TÍTOL" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTISTA [ ÀLBUM ] - PISTA. TÍTOL" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ÀLBUM - TÍTOL" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Categoria" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Personalitzat" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Format del títol:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Cadena personalitzada:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Habilita l'enregistrament del flux d'àudio amb %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "No hi ha disponible cap connector d'enregistrament d'àudio" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Ajusts d'Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Cancel·la" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Desa" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Carrega" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Carrega el fitxer dels valors preestablerts" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Carrega el fitxer EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Desa el fitxer dels valors preestablerts" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Desa el fitxer EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Gestor de cues" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Desfés la cua" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "S'està treballant..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Error" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Informació" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "De_sa a l'historial" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Obre l'URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Afegeix l'URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "Neteja l'historia_l" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Introduïu l'URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Obre" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Els missatges següents han estat amagats)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Tanca" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Explora" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Obre la carpeta" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Afegeix la carpeta" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Afegeix" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadades" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Compositor" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Artista" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Any de l'enregistrament" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Data de l'enregistrament" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Tècnic" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Taxa de bits" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Nivell" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Funció" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Missatge" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Inspector del registre" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Depuració" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Info" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Advertència" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "N_eteja" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Nivell de registre:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Serveis" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Copia" diff --git a/po/cmn.po b/po/cmn.po new file mode 100644 index 0000000..55b031d --- /dev/null +++ b/po/cmn.po @@ -0,0 +1,1504 @@ +# Chinese (Mandarin) translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Ruei-Yuan Lu , 2011 +# whhone , 2013 +# 趙惟倫 , 2013 +# whhone , 2013 +# 趙惟倫 , 2013 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: 趙惟倫 \n" +"Language-Team: Chinese (Mandarin) (http://www.transifex.com/audacious/audacious/language/cmn/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: cmn\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "顯示版本資訊" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "若播放中則暫停,否則繼續播放" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "加入檔案至播放列表" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "顯示主視窗" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "播放停止後離開" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "找到 %d 個檔案" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "" + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "新播放列表" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "音樂 CD,音軌 %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "正在播放" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "單聲道" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "立體聲" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d 聲道" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "音樂 CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "開發團隊" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "授權條款" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "關於 Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "重新命名(_R)" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "重新命名播放列表" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "匯入" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "啟用(_E)" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "等化器" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "" + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "前置放大" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "開啟檔案" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "加入檔案" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "關閉(_C)" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "標題" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "演出者" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "專輯" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "類型" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "年分" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "音軌" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "長度" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "格式:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "品質:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "迷幻爵士" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "迷幻搖滾" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "氛圍音樂" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "藍草" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "藍調" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "室內樂" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "古典" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "鄉村" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "死亡金屬" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "迪斯可" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "輕音樂" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "民謠" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "放客" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "黑幫說唱" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "福音音樂" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "垃圾搖滾" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "硬式搖滾" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "重金屬" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "嘻哈" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "爵士" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "叢林" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "金屬" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "新世紀" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "新浪潮" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "噪音" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "流行" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "龐克搖滾" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "說唱" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "雷鬼" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "搖滾 (Rock)" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "搖滾 (Rock&Roll)" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "R&B" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "靈魂" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "搖擺樂" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "數位" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "迷幻舞曲" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "歌曲資訊" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "備註" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "下一首(_N)" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "跳至時間" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "請輸入時間 (分:秒):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "排入佇列(_Q)" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "移出佇列(_Q)" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "跳至歌曲" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "過濾器:" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "過濾器(_F):" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "覆寫 %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "匯出播放列表" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "匯入播放列表" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "" + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "關於 %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s 設定" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "選擇資料夾" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "音訊" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "網路" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "播放列表" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "外掛" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "一般" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "特效" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "視覺特效" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "輸入" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "傳輸" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "檔案名稱" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "檔案路徑" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "日期" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "編解碼器" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "品質" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "無" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "阿拉伯語" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "波羅的海" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "漢語" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "希臘語" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "希伯來語" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "日本語" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "韓語" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "波蘭語" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "俄語" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "傳統字漢語" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "土耳其語" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "浮點數" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "輸出外掛:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "放大所有檔案的音量:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "分貝" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "放大無標籤檔案的音量:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "輸出設定" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "取樣格式:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "緩衝區大小:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "毫秒" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "軟性削峰" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "使用軟體音量控制 (不建議開啟)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "防止訊號裁剪 (建議開啟)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "代理伺服器名稱:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "代理伺服器通訊埠:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "代理伺服器使用者名稱:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "代理伺服器密碼:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "代理伺服器設定" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "啟用代理伺服器" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "需要認證" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "自動偵測字元編碼:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "備用字元編碼:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "行為" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "目前的歌曲被刪除時移至下一首" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "開啟檔案後清除播放列表" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "在暫存播放列表中開啟檔案" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "顯示歌曲" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "顯示歌曲編號" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "專輯封面" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "搜尋符合這些單字的圖片 (以逗號分隔):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "排除符合這些單字的圖片 (以逗號分隔):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "搜尋符合歌曲檔名的圖片" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "遞迴搜尋" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "搜尋深度:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "彈出式資訊視窗" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "顯示彈出式資訊視窗" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "彈出視窗的延遲時間 (十分之一秒):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "顯示目前歌曲的時間軸" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "相容性" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "將 \\ (反斜線) 視為資料夾分隔符號" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "詮釋資料" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "在歌曲播放以前不要載入詮釋資料" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "其他選項" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "秒" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "標題" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "演出者 - 標題" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "演出者 - 專輯 - 標題" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "演出者 - 專輯 - 音軌. 標題" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "演出者 [ 專輯 ] - 音軌. 標題" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "專輯 - 標題" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "目錄" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "自訂" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "標題格式:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "自訂字串:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "取消" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "儲存" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "載入" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "佇列管理" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "" + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "錯誤" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "開啟網址" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "加入網址" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "請輸入網址:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(詳細訊息已被隱藏。)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "瀏覽" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "位元率" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "拷貝" diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 0000000..61b44ed --- /dev/null +++ b/po/cs.po @@ -0,0 +1,1522 @@ +# Czech translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Jiří Vírava , 2012 +# fri, 2012 +# fri, 2012-2013 +# hpsoft , 2014 +# Jan Nárovec , 2004 +# Andy Andy , 2014 +# Jiří Vírava , 2012 +# Jiří Vírava , 2012 +# hpsoft , 2014 +# Lukáš Kotek , 2020 +# IAmNotImportant, 2016 +# Andy Andy , 2014-2015 +# fri, 2013-2014 +# fri, 2012 +# Petr Písař , 2007-2012 +# Petr Šimáček , 2014,2017 +# Roman Horník , 2016,2018 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-04-02 15:37+0000\n" +"Last-Translator: Lukáš Kotek \n" +"Language-Team: Czech (http://www.transifex.com/audacious/audacious/language/cs/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: cs\n" +"Plural-Forms: nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Zobrazit nápovědu příkazového řádku" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Zobrazit verzi" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Zahájit přehrávání" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pozastavit přehrávání" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pozastaví při přehrávání; jinak spustí" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Zastavit přehrávání" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Přeskočit k předchozí skladbě" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Přeskočit k následující skladbě" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Přidat soubory do do seznamu skladeb" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Přidat soubory do dočasného playlistu" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Zobrazit hlavní okno" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Ukázat okno s přeskakováním skladeb" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Spustit bez grafického rozhraní" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Ukončit po zastavení přehrávání" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Zobrazit zprávy o ladění (může být použito dvakrát)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Spustit v režimu GTK" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Neznámá volba: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Neznámá volba: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Použití: audacious [OPTION] ... [FILE] ...\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Zvolte instanci pro spuštění/ovládání" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Nalezen %d soubor" +msgstr[1] "Nalezeny %d soubory" +msgstr[2] "Nalezeno %d souborů" +msgstr[3] "Nalezeno %d souborů" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Chyba při čtení %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Nenalazeny žádné soubory." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nový seznam skladeb" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Standardní vstup" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Zvukové CD, stopa %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(chyba kódování znaků)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Nahrávání streamu musí být před použitím nakonfigurováno v nastavení zvuku." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Chyba při otevírání výstupního proudu" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Chyba při zaznamenávání výstupního proudu" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Chyba přehrávání %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Neplatný zvukový formát" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Nyní hraje" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Chyba při otevírání %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Chyba při nahrávání %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Nemohu nahrát %s: nepodporovaná přípona souboru." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Chyba během ukládání %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Nemohu uložit %s: nepodporovaná přípona souboru." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Chyba při nahrávání přídavného modulu" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Chyba při hledání" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Formát souboru nerozpoznán" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Chyba při čtení popisných dat" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanál" +msgstr[1] "%d kanály" +msgstr[2] "%d kanálů" +msgstr[3] "%d kanálů" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Zvukové CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Stopa %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(neznámý název)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Neznámé schéma URI" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Neplatné jméno souboru" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Chybný režim přístupu" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Zásluhy" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licence" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "O Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Zrušit" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Neptat se znovu" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Opravdu chcete trvale odstranit \"%s\"?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Smazat" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Smazat playlist" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Chcete načíst tento playlist?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Přejmenovat" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Přejmenovat seznam skladeb" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Prosím vyberte předvolbu pro export." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Soubor předvoleb ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Soubor EQF ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Import" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Export" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Předvolby ekvalizéru" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Ulož předvolbu" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Smaž vybrané" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Zvrátit změny" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Zapnout" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Ekvalizér" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Předvolby ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Reset na nulu" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Předzesílení" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Otevřít soubory" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Otevřít" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Zavřít _dialog při otevření" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Přidat soubory" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Přidat" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Zavřít _dialog při přidání" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Zavřít" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Název" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Umělec" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Žánr" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Rok" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Stopa" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Délka" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formát:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Kvalita:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Datový tok Bitrate: " + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebob" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Komorní hudba" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klasika" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disko" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Příjemné poslouchání" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "Nová vlna" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "R&B" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Ukládání proběhlo úspěšně" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Chyba při ukládání" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Informace o skladbě" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Album Umělec" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Komentář" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Číslo stopy" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "_Automaticky vyplnit prázdná pole" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Ulozit" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Předchozí" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Další" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "Nedostupné" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Přeskočit" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Přejít na čas" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Zadejte čas (minuty: sekundy):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Fronta" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Ode_brat z fronty" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Přejít na skladbu" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtr: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtr:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Zavřít při skoku" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Přepsat" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Potvrdit přepsání" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Přepsat %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Prosím napiš příponu souboru nebo vyber formát ze seznamu" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Vyber formát podle přípony" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Exportovat seznam skladeb" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exportovat" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importovat seznam skladeb" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importovat" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Doplňky ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "O %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Nastavení" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Nastavit" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Nastavení" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_O programu" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Vybrat soubor" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Vybrat složku" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Vzhled" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Zvuk" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Síť" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Seznam skladeb" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Moduly" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Pokročilé" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Obecné" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efekt" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Znázornění" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Vstup" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Přenos" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Umělec alba" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Číslo stopy" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Jméno souboru" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Cesta k souboru" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Datum" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Popis" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Kodek" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Kvalita" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Žádné" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arabština" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltské jazyky" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Čínština" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Řečtina" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebrejština" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japonština" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Korejština" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polština" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Ruština" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Tchajwanština" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turečtina" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automaticky" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Plovoucí desetiná čárka" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Dekódováno" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Po použití ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Po použití efektů" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Po použití ekvalizace" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Na základě přeházení" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Rozhraní:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Výstupní modul:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Zesílit všechny soubory:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Zesílit soubory bez popisků:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Nastavení výstupu" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bitová hloubka:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Velikost vyrovnávací paměti:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Měkké oříznutí" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Hlasitost ovládat softwarově (nedoporučuje se)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Nastavení záznamu" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Zaznamenat proud:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Povolit ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Mód:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Předcházet ořezu (doporučuje se)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Jméno počítače:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Port:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Jméno:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Heslo:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Síťová nastavení" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Nastavení proxy" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Používat proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Použít ověřování pomocí proxy serveru" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Použít SOCKS proxy" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automatické rozpoznávání kódovaní znaků:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Záložní kódování znaků:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Chování" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Pokračovat v přehrávání po spuštění" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pozastavit namísto okamžitého pokračování v přehrávání" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Přejít dál, když současná skladba je smazána" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Při otevírání souborů vyprázdnit seznam skladeb" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Otevřít soubory do dočasného seznamu skladeb" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Zobrazení skladby" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Zobrazovat čísla skladeb" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Zobrazit úvodní nuly (02:00 oproti 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Zobrazit hodiny odděleně (1:30:00 oproti 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exportovat" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Použít relativní cesty kdykoliv je to možné" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Album" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Vyhledat obrázky odpovídající těmto slovům (oddělené čárkou):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Vyloučit obrázky vyhovují těmto slovům (oddělené čárkou):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Hledat obrázky odpovídající názvu hudebního souboru" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Hledat rekurzivně" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Hloubka prohledání:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Vyskakovací okno s podrobnostmi" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Zobrazit informace ve vyskakovacím oknu" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Popup zpoždění (desetiny sekundy):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Zobrazit časové měřítko pro aktuální skladby" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Kompatibilita" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpretovat \\ (zpětné lomítko) jako oddělovač složek" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Playlist" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Přidat složky rekurzivně" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Přidat složky vnořené do souborů playlistu" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadata" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Uhodnout chybějící metadata z cesty souboru" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Nenačítat popisná data skladeb před přehráním" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Prozkoumat obsah souborů, u kterých není rozeznána přípona souboru" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Různé" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Krok vpřed/zpět pomocí:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "sekund" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Přizpůsobit hlasitost pomocí:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "procento" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "NÁZEV" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "NÁZEV - UMĚLEC" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "NÁZEV - UMĚLEC - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "UMĚLEC – NÁZEV" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "UMĚLEC – ALBUM – NÁZEV" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "UMĚLEC – ALBUM – STOPA. NÁZEV" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "UMĚLEC [ ALBUM ] – STOPA. NÁZEV" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM – NÁZEV" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategorie" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Vlastní" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Formát názvu:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Vlastní řetězec:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Povolit nahrávání zvukových proudů pomocí %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Žádný modul na nahrávání zvuku není dostupný" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Nastavení Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Zruš" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Ulož" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Nahraj" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Nahraj předvolby" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Nahraj EQF soubor" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Ulož předvolby" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Ulož EQF soubor" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Správce fronty" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Vyřadit z fronty" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Pracuje..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Chyba" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Informace" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Uložit do historie" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Otevřít URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Přidat URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "_Vyčistit historii" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Zadejte URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Otevřít" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Další zprávy jsou skryty.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Soubory s předvolbami (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Zavřít" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Procházet" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Otevřít složku" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Přidat složku" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Přidat" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Nastavit písmo" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Popisná data" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Skladatel" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Účinkující" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Rok nahrání" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Datum nahrání" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Technický" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Datový tok" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "MusicBrainz ID" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Vrátit" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Chyba během zapisování tagu (tagů)." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 souborů vybráno" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "_Uložit %1 souborů" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Úroveň" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Funkce" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Zpráva" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Inspektor logů" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Ladění" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Informace" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Varování" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Vy_mazat" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Úroveň záznamu:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Služby" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopírovat" diff --git a/po/da.po b/po/da.po new file mode 100644 index 0000000..1029315 --- /dev/null +++ b/po/da.po @@ -0,0 +1,1503 @@ +# Danish translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Joe Hansen , 2013-2014,2016,2020 +# scootergrisen, 2017-2018 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-05-12 10:00+0000\n" +"Last-Translator: Joe Hansen \n" +"Language-Team: Danish (http://www.transifex.com/audacious/audacious/language/da/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: da\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Vis hjælp for kommandolinje" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Vis version" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Start afspilning" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Sæt afspilning på pause" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Sæt på pause hvis der afspilles, ellers afspilles der" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Stop afspilning" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Gå til forrige sang" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Gå til næste sang" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Tilføj filer til afspilningslisten" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Tilføj filer til en midlertidig afspilningsliste" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Vis hovedvinduet" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Vis hop til sang-vinduet" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Start uden en grafisk grænseflade" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Afslut når afspilning stopper" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Udskriv fejlsøgningsbeskeder (kan bruges to gange)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Kør i GTK-tilstand" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Ukendt tilvalg: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Ukendt tilvalg: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Brug: audacious [TILVALG] ... [FIL] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Vælg instans til kør/kontrol" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d fil fundet" +msgstr[1] "%d filer fundet" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Fejl ved læsning af %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Ingen filer fundet." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Ny afspilningsliste" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Standardind" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Lyd-cd, spor %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(tegnkodningsfejl)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Strømoptagelse skal være konfigureret i lydindstillinger inden det kan bruges." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Fejl ved åbning af outputstrøm" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Fejl ved optagelse af outputstrøm" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Fejl under afspilning af %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Ugyldigt lydformat" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Afspiller nu" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Fejl under åbning af %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Fejl under indlæsning af %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Kan ikke indlæse %s: navnet på filendelsen er ikke understøttet." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Kunne ikke gemme %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Kan ikke gemme %s: navnet på filendelsen er ikke understøttet." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Fejl ved indlæsning af udvidelsesmodul" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Søgefejl" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Filformatet blev ikke genkendt" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Fejl under læsning af metadata" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanal" +msgstr[1] "%d kanaler" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Lyd-cd" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Spor %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(ukendt titel)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Ukendt URI-skema" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Ugyldigt filnavn" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Ugyldig adgangstilstand" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Krediteringer" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licens" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Om Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Annuller" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Spørg ikke igen" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Vil du fjerne »%s« permanent?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Fjern" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Fjern afspilningsliste" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Hvad vil du kalde denne afspilningsliste?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Omdøb" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Omdøb afspilningsliste" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Vælg venligst en forhåndsindstilling at eksportere" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Forhåndsindstillingsfil ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF-fil ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importér" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Eksportér" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Equalizerforhåndsindstillinger" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Gem forhåndsindstilling" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Slet valgte" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Omgør ændringer" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Aktivér" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Equalizer" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Forhåndsindstillinger ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Nulstil til nul" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamp" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Åbn filer" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Åbn" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Luk _dialog ved åbn" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Tilføj filer" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Tilføj" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Luk _dialog ved tilføjelse" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Luk" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Titel" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Kunstner" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Genre" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "År" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Spor" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Længde" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Format:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Kvalitet:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bithastighed:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Kammermusik" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klassisk" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Dødsmetal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disko" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Blød pop" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsterrap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hård rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavymetal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Larm" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock og rul" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rytme og blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Tekno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Gemt med succes" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Fejl under gemning" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Sanginformation" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Kunstner" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Kommentar" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Spornummer" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "_Udfyld automatisk tomme felter" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Gem" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Forrige" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Næste" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "-" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Hop" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Hop til tidspunkt" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Indtast tidspunkt (minutter:sekunder):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Sæt i kø" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "_Fjern fra kø" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Hop til sang" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filter: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filter:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "_Luk ved hop" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Overskriv" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Bekræft overskriv" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Overskriv %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Indtast en filnavnendelse eller vælg et format fra rullegardinet." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Vælg format efter filendelse" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Eksportér afspilningsliste" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Eksportér" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importér afspilningsliste" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importér" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Udvidelsesmoduler ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Om %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Indstillinger for %s" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Angiv" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Indstillinger" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Om" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Vælg fil" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Vælg mappe" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Udseende" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Lyd" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Netværk" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Afspilningsliste" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Udvidelsesmoduler" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Avanceret" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Generelt" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Effekt" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualisering" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Lydindgang" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transport" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Kunstner" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Spornummer" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Filnavn" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Filsti" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Dato" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Beskrivelse" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Kodning" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Kvalitet" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Ingen" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arabisk" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltisk" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Kinesisk" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Græsk" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebraisk" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japansk" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Koreansk" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polsk" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Russisk" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanesisk" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Tyrkisk" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automatisk" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Flydende kommatal" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Som afkodet" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Efter anvendelse af ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Efter anvendelse af effekter" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Efter anvendelse af equalization" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Baseret på bland" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Grænseflade:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Udvidelsesmodul for lydudgang:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Forstærk alle filer:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Forstærk umærkede filer:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Indstillinger for lydudgang" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bitdybde:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Bufferstørrelse:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Blød beskæring" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Brug programmets styring af lydstyrken (anbefales ikke)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Optageindstillinger" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Optagestrøm:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Aktivér ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Tilstand:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Forhindr kliklyde (anbefales)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Proxyens værtsnavn:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Proxyens port:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Proxyens brugernavn:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Proxyens adgangskode:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Netværksindstillinger" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Konfiguration af proxy" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Aktivér brug af proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Brug godkendelse med proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Brug SOCKS-proxy" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automatisk tegnkodningsdetektor for:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Reservetegnkodninger:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Opførsel" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Genoptag afspilning ved opstart" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pause i stedet for at genoptage øjeblikkeligt" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Gå videre når den nuværende sang er slettet" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Ryd afspilningslisten når der åbnes filer" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Åbn filer i midlertidig afspilningsliste" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Sangvisning" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Vis sangenes numre" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Vis indledende nuller (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Vis timer separat (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Eksportér" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Brug relative stier når det er muligt" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Albumomslag" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Søg efter billeder der matcher disse ord (kommaadskilt):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Ekskulder billeder der matcher disse ord (kommaadskilt):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Søg efter billeder der matcher sangens filnavn" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Søg rekursivt" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Søgedybde:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Pop op-information" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Vis pop op-information" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Forsinkelse af pop op (tiendedele sekund):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Vis tidsskala for nuværende sang" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Kompatibilitet" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Fortolk \\ (baglæns skråstreg) som en mappeafgrænser" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Afspilningsliste" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Tilføj mapper rekursivt" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Tilføj mapper som er indlejret indeni afspilningslistens filer" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadata" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Gæt manglende metadata fra filsti" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Indlæs ikke metadata for sange inden de afspilles" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Undersøg indholdet af filer uden et genkendt navn på filendelserne" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Diverse" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Trin fremad/tilbage med:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "sekunder" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Juster lydstyrke med:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "procent" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TITEL" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TITEL - KUNSTNER" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TITEL - KUNSTNER - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "KUNSTNER - TITEL" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "KUNSTNER - ALBUM - TITEL" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "KUNSTNER - ALBUM - SPOR. TITEL" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "KUNSTNER [ ALBUM ] - SPOR. TITEL" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - TITEL" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategori" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Tilpasset" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Titelformat:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Tilpasset streng:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Aktivér optagelse af lydstrøm med %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Intet udvidelsesmodul til lydoptagelse er tilgængeligt" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Indstillinger for Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Annuller" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Gem" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Indlæs" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Indlæs forhåndsindstillingsfil" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Indlæs EQF-fil" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Gem forhåndsindstillingsfil" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Gem EQF-fil" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Håndtering af kø" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Fjern fra kø" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Arbejder ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Fejl" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Information" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Gem til historik" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Åbn URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Tilføj URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "_Ryd historik" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Indtast URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Åbn" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Yderligere beskeder er blevet skjult)." + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Forhåndsindstillingsfiler (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Luk" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Gennemse" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Åbn mappe" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Tilføj mappe" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Tilføj" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Angiv skrifttype" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadata" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Komponist" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Artist" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Optagelsesår" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Optagelsesdato" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Teknisk" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bithastighed" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "MusicBrainz-id" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Fortryd" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Kunne ikke skrive mærker." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 filer valgt" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "_Gem %1 filer" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Niveau" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Funktion" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Besked" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Loginspektør" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Fejlsøg" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Info" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Advarsel" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "_Ryd" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Logniveau:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Tjenester" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopiér" diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..138d4c4 --- /dev/null +++ b/po/de.po @@ -0,0 +1,1511 @@ +# German translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Chris , 2012 +# Chris , 2012 +# Ettore Atalan , 2016 +# mschwendt , 2012 +# mschwendt , 2012 +# Chris , 2012 +# Thomas Lange, 2011 +# Thomas Lange, 2011 +# Thomas Lange, 2011 +# Thomas Lange, 2011,2014-2015 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:55+0000\n" +"Last-Translator: Thomas Lange\n" +"Language-Team: German (http://www.transifex.com/audacious/audacious/language/de/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Befehlszeilenhilfe anzeigen" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Version anzeigen" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Wiedergabe starten" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Wiedergabe pausieren" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Wiedergabe pausieren falls aktiv, sonst starten" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Wiedergabe stoppen" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Zu nächstem Titel springen" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Zu vorherigen Titel springen" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Dateien zur Wiedergabeliste hinzufügen" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Dateien zu temporärer Wiedergabeliste hinzufügen" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Hauptfenster anzeigen" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "»Zu Titel springen«-Fenster anzeigen" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Ohne grafische Benutzeroberfläche starten" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Nach dem Ende der Wiedergabe beenden" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Debugmeldungen anzeigen" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Im GTK Modus ausführen" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Unbekannte Option: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Unbekannte Option: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Aufruf: audacious [OPTION] ... [DATEI] ...\n \n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Instanz für Ausführung/Steuerung auswählen" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d Datei gefunden" +msgstr[1] "%d Dateien gefunden" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Fehler beim Lesen von %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Keine Dateien gefunden." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Neue Wiedergabeliste" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Standardeingabe" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Audio-CD, Titel »%s«" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(Fehler bei Zeichencodierung)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Die Aufnahme von Streams muss zuerst in den Audioeinstellungen konfiguriert werden." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Fehler beim Öffnen des Ausgabestreams" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Fehler beim Aufnehmen des Ausgabestreams" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Fehler beim Abspielen von %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Ungültiges Audioformat" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Momentane Wiedergabe" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Fehler beim Öffnen von %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Fehler beim Laden von »%s«." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Laden von »%s« nicht möglich: nicht unterstützte Dateiendung." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Fehler beim Speichern von »%s«." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Speichern von »%s« nicht möglich: nicht unterstützte Dateiendung." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Fehler beim Laden des Plugins" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Suchfehler" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Dateiformat nicht erkannt" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Fehler beim Lesen der Metadaten" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d Kanal" +msgstr[1] "%d Kanäle" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Audio-CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Titel %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(unbekannter Titel)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Unbekanntes URI Schema" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Ungültiger Dateiname" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Ungültiger Zugriffsmodus" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Mitwirkende" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Lizenz" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Info zu Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Abbrechen" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Nicht mehr fragen" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Wollen Sie wirklich »%s« dauerhaft löschen?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Löschen" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Wiedergabeliste löschen" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Wie soll diese Wiedergabeliste heißen?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Umbenennen" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Wiedergabeliste umbenennen" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Bitte wählen Sie eine zu exportierende Voreinstellung." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Voreinstellungen-Datei ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF-Datei ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importieren" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exportieren" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Equalizer Voreinstellungen" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Voreinstellung speichern" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Ausgewählte löschen" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Änderungen zurücknehmen" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Aktiv" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Equalizer" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Voreinstellungen ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Auf Null zurücksetzen" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Vorverstärkung" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Dateien öffnen" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "Ö_ffnen" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "_Dialog beim Öffnen schließen" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Dateien hinzufügen" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Hinzufügen" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "_Dialog beim Hinzufügen schließen" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "S_chließen" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Titel" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Künstler" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Genre" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Jahr" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Nummer" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Dauer" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Format:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Qualität:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bitrate:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Psychedelic Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Kammermusik" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klassisch" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-Hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock ’n’ Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm & Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-Hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Speichern erfolgreich" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Speichern fehlgeschlagen" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Titelinfo" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Album-Künstler" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Kommentar" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Titelnummer" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "Leere Felder _automatisch füllen" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Speichern" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Vorheriger" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Nächster" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/V" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Springen" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Zu Zeitangabe springen" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Zeitangabe (Minuten:Sekunden):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "In _Warteschlange" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Aus _Warteschlange" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Zu Titel springen" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filter: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filter:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "_Nach Springen schließen" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "Über_schreiben" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Überschreiben bestätigen" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "»%s« überschreiben?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Bitte geben Sie eine Dateiendung an oder wählen Sie ein Format aus der Dropdown-Liste." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Format aus Dateiendung auswählen" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Wiedergabeliste exportieren" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exportieren" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Wiedergabeliste importieren" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importieren" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Plugins ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Info zu %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Einstellungen" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Setzen" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Einstellungen" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Info" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Datei auswählen" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Ordner auswählen" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Aussehen" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Audio" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Netzwerk" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Wiedergabeliste" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Plugins" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Erweitert" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Allgemein" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Effekte" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualisierung" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Eingabe" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transport" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Album-Künstler" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Titelnummer" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Dateiname" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Dateipfad" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Datum" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Beschreibung" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Codec" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Qualität" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Keine" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arabisch" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltisch" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Chinesisch" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Griechisch" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebräisch" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japanisch" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Koreanisch" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polnisch" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Russisch" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanisch" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Türkisch" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automatisch" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Gleitkomma" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Wie dekodiert" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Nach Anwendung der Wiedergabeverstärkung" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Nach Anwendung von Effekten" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Nach Anwendung des Equalizers" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Anhand Zufallswiedergabe" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interface:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Ausgabe-Plugin:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Alle Dateien verstärken:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Unmarkierte Dateien verstärken:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Ausgabeeinstellungen" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bittiefe:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Puffergröße:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Softwareseitige Amplitudenbegrenzung" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Softwareseitige Lautstärkeregelung benutzen (nicht empfohlen)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Aufnahmeeinstellungen" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Stream aufnehmen:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "Wiedergabeverstärkung" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Wiedergabeverstärkung aktivieren" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Modus:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Übersteuern verhindern (empfohlen)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Proxy-Host:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Proxy-Port:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Benutzername für Proxy:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Passwort für Proxy:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Netzwerkeinstellungen" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Proxy Konfiguration" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Proxy aktivieren" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Benutze Authentisierung mit Proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Benutze SOCKS Proxy" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automatische Zeichensatzerkennung für:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Alternative Zeichensätze:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Verhalten" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Wiedergabe beim Starten fortsetzen" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pausieren anstatt Wiedergabe fortsetzen" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Fortschreiten, falls aktueller Titel gelöscht wird" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Wiedergabeliste beim Öffnen neuer Dateien leeren" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Dateien in temporärer Wiedergabeliste öffnen" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Titelanzeige" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Zeige Titelnummern" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Führende Nullen anzeigen (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Stunden separat anzeigen (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Export" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Benutze relative Pfade wenn möglich" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Album-Cover" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Nach Bildern suchen, die diese Wörter enthalten (durch Kommas getrennt):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Bilder ausschließen, die diese Wörter enthalten (durch Kommas getrennt):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Nach Bildern suchen, die mit dem Dateinamen des Titels übereinstimmen" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Rekursiv suchen" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Suchtiefe:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Popup-Informationen" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Popup-Informationen anzeigen" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Popup-Verzögerung (Zehntel einer Sekunde):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Fortschrittsbalken für aktuellen Titel anzeigen" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Kompatibilität" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpretiere \\ (Backslash) als Pfadtrennzeichen" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Wiedergabeliste" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Ordner rekursiv hinzufügen" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Ordner hinzufügen, die in Wiedergabelisten verschachtelt sind" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadaten" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Fehlende Metadaten aus Dateipfad erraten" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Metadaten erst laden, wenn Titel gespielt wird" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Inhalt von Dateien ohne erkannte Dateiendung untersuchen" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Verschiedenes" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Vor-/zurückspringen um:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "Sekunden" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Lautstärke anpassen um:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "Prozent" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TITEL" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TITEL - KÜNSTLER" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TITEL - KÜNSTLER - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "KÜNSTLER - TITEL" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "KÜNSTLER - ALBUM - TITEL" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "KÜNSTLER - ALBUM - TITELNUMMER. TITEL" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "KÜNSTLER [ ALBUM ] - TITELNUMMER. TITEL" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - TITEL" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategorie" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Benutzerdefiniert" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Titelformat:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Eigene Zeichenkette:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Aufnahme von Audio-Streams mit »%s« aktivieren" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Kein Aufnahmeplugin für Audio vorhanden" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious Einstellungen" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Abbrechen" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Speichern" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Laden" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Voreinstellung laden" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "EQF-Datei laden" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Voreinstellung speichern" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "EQF-Datei speichern" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Warteschlangen-Manager" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "Aus _Warteschlange" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "In Bearbeitung ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Fehler" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Information" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "In Chronik _speichern" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "URL öffnen" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "URL hinzufügen" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "Chronik _leeren" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "URL eingeben:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Öffnen" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Weitere Meldungen wurden nicht angezeigt.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Voreinstellungen (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Schließen" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Durchsuchen" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Ordner öffnen" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Ordner hinzufügen" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Hinzufügen" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Schriftart setzen" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadaten" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Komponist" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Interpret" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Aufnahmejahr" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Aufnahmedatum" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Technisch" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bitrate" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "MusicBrainz-ID" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "Zu_rücknehmen" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Fehler beim Schreiben der Tags." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 Dateien ausgewählt" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "%1 Dateien _speichern" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Level" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Funktion" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Meldung" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Protokoll-Inspektor" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Debug" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Information" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Warnung" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "_Leeren" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Logging-Level:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Dienste" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopieren" diff --git a/po/el.po b/po/el.po new file mode 100644 index 0000000..4d2a001 --- /dev/null +++ b/po/el.po @@ -0,0 +1,1515 @@ +# Greek translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# gis mapps , 2014 +# Ioannis LM, 2018,2020 +# Ioannis LM, 2018,2020 +# Marinos Zak , 2012 +# Marinos Zak , 2012 +# Marinos Zak , 2012 +# Michael Misirlis , 2015 +# Stathis Kamperis , 2006 +# Wasilis Mandratzis-Walz, 2015 +# Wasilis Mandratzis-Walz, 2015 +# Yannis Anthymidis, 2011 +# Yannis Anthymidis, 2011 +# Γιάννης Ανθυμίδης, 2011 +# Yannis Anthymidis, 2011-2014 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-04-19 07:34+0000\n" +"Last-Translator: Ioannis LM\n" +"Language-Team: Greek (http://www.transifex.com/audacious/audacious/language/el/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: el\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Προβολή βοήθειας για τη γραμμή εντολών" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Εμφάνιση έκδοσης" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Έναρξη αναπαραγωγής" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Παύση αναπαραγωγής" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Παύση αν παίζει, αλλιώς αναπαραγωγή" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Διακοπή αναπαραγωγής" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Μετάβαση στο προηγούμενο κομμάτι" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Μετάβαση στο επόμενο κομμάτι" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Προσθήκη αρχείων στη λίστα αναπαραγωγής" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Προσθήκη αρχείων σε προσωρινή λίστα αναπαραγωγής" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Εμφάνιση του κυρίως παραθύρου" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Εμφάνιση του παραθύρου άλμα-σε-τραγούδι" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Έναρξη χωρίς γραφικό περιβάλλον" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Έξοδος στη διακοπή της αναπαραγωγής" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Προβολή μηνυμάτων εντοπισμού σφαλμάτων (μπορεί να χρησιμοποιηθεί δύο φορές)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Εκτέλεση σε λειτουργία GTK" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Άγνωστη επιλογή: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Άγνωστη επιλογή: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Χρήση: audacious [ΕΠΙΛΟΓΗ] ... [Αρχείο] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Επιλογή υπόδειξης για εκτέλεση/έλεγχο" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Βρέθηκε %d αρχείο" +msgstr[1] "Βρέθηκαν %d αρχεία" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Σφάλμα ανάγνωσης %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Δεν βρέθηκαν αρχεία." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Νέα λίστα αναπαραγωγής" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Τυπική είσοδος" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Μουσικό CD, κομμάτι %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(χαρακτήρας σφάλμα κωδικοποίησης)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Πρέπει να ενεργοποιήσετε τη εγγραφή ηχητικής ροής στις ρυθμίσεις του ήχου, πριν τη χρησιμοποιήσετε." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Σφάλμα στο άνοιγμα της ηχητικής ροής" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Σφάλμα στην εγγραφή της ηχητικής ροής" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Σφάλμα κατά την αναπαραγωγή του %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Μη έγκυρη μορφή ήχου" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Αναπαράγεται τώρα" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Σφάλμα ανοίγματος του %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Σφάλμα φόρτωσης %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Δεν είναι δυνατή η φόρτωση του %s: δεν υποστηρίζεται η επέκταση του ονόματος στο αρχείο." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Αποθήκευση σφάλματος %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Δεν είναι δυνατή η αποθήκευση του αρχείου %s: δεν υποστηρίζεται η επέκταση του ονόματος στο αρχείο." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Σφάλμα κατά τη φόρτωση του πρόσθετου" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Αναζήτηση σφάλματος" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Δεν αναγνωρίζεται η μορφή του αρχείου" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Σφάλμα ανάγνωσης μεταδεδομένων" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Μονοφωνικό" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Στερεοφωνικό" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d κανάλι" +msgstr[1] "%d κανάλια" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Μουσικό CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Κομμάτι %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(Άγνωστος τίτλος)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Άγνωστο σχήμα URI" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Μη έγκυρο όνομα αρχείου" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Μη έγκυρη λειτουργία πρόσβασης" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Μνεία" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Άδεια" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Σχετικά με το Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "Ά_κυρο" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Να μην ερωτηθώ ξανά" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Θέλετε να αφαιρέσετε οριστικά την “%s”;" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "Α_φαίρεση" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Αφαίρεση λίστας αναπαραγωγής" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Πώς θέλετε να ονομάσετε τη λίστα αναπαραγωγής;" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Μετονομασία" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Μετονομασία λίστας αναπαραγωγής" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Παρακαλώ επιλέξτε μια προεπιλογή για την εξαγωγή." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Αρχείο προκαθορισμένων τιμών ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Αρχείο EQF ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Εισαγωγή" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Εξαγωγή" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Προκαθορισμένες τιμές ισοσταθμιστή" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Αποθήκευση προκαθορισμένων τιμών" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Διαγραφή επιλεγμένων" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Επαναφορά αλλαγών" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Ενεργοποίηση" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Ισοσταθμιστής" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Προκαθορισμένες τιμές ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Επαναφορά στο μηδέν" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Προενίσχυση" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Άνοιγμα αρχείων" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Άνοιγμα" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Κλείσιμο του παρα_θύρου στο άνοιγμα" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Προσθήκη αρχείων" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Προσθήκη" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Κλείσιμο του παραθύρου στη π_ροσθήκη" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Κλείσιμο" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Τίτλος" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Καλλιτέχνης" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Άλμπουμ" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Είδος" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Έτος" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Κομμάτι" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Διάρκεια" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Μορφή:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Ποιότητα:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Ρυθμός διαμεταγωγής (bitrate)" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Chamber Music" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Κλασική Μουσική" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Επιτυχής αποθήκευση" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Σφάλμα κατά την αποθήκευση" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Πληροφορίες κομματιού" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Καλλιτέχνης άλμπουμ" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Σχόλιο" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Αριθμός κομματιού" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "_Αυτόματη συμπλήρωση κενών πεδίων" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Αποθήκευση" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Προηγούμενο" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Επόμενο" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kΒ/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/A" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Μετάβαση" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Μετάβαση σε χρόνο" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Πληκτρολογήστε το χρόνο (λεπτά: δευτερόλεπτα):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Στη σειρά" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Αφ_αίρεση από τη σειρά" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Μετάβαση στο τραγούδι" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Φίλτρο: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Φιλτράρισμα:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Κλείσιμο στη Μετάβαση" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Αντικατάσταση" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Επιβεβαίωση αντικατάστασης" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Να γίνει αντικατάσταση του %s;" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Παρακαλώ δώστε την επέκταση του αρχείου ή επιλέξτε από την αναπτυσσόμενη λίστα." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Επιλογή μορφής από την επέκταση" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Εξαγωγή λίστας αναπαραγωγής" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "Ε_ξαγωγή" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Εισαγωγή λίστας αναπαραγωγής" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Εισαγωγή" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "Π_ρόσθετα ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Σχετικά με το %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Ρυθμίσεις" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Ορισμός" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Ρυθμίσεις" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Περί" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Επιλογή αρχείου" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Επιλογή φακέλου" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Εμφάνιση" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Ήχος" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Δίκτυο" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Λίστα αναπαραγωγής" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Πρόσθετα" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Προχωρημένα" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Γενικά" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Εφέ" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Απεικόνιση" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Γραμμή εισόδου" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Μεταφορά" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Καλλιτέχνης άλμπουμ" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Αριθμός κομματιού" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Όνομα αρχείου" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Διαδρομή αρχείου" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Ημερομηνία" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Περιγραφή" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Κωδικοποιητής" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Ποιότητα" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Κανένα" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Αραβικά" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Βαλτικά" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Κινέζικα" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Ελληνικά" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Εβραϊκά" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Ιαπωνικά" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Κορεάτικα" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Πολωνικά" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Ρώσικα" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Ταϊβανέζικα" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Τούρκικα" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Αυτόματα" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Κινητή υποδιαστολή" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Όπως αποκωδικοποιείται" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Μετά από την εφαρμογή ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Μετά από την εφαρμογή ενεργειών" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Μετά από την εφαρμογή εξισορρόπησης" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Με βάση τη τυχαία εναλλαγή" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Διεπαφή:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Πρόσθετο γραμμής εξόδου:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Ενίσχυση όλων των αρχείων:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Ενίσχυση αρχείων χωρίς tags:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Ρυθμίσεις εξόδου" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Βάθος bit:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Μέγεθος προσωρινής μνήμης:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Soft clipping" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Χρήση λογισμικού ελέγχου έντασης (δεν συνιστάται)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Ρυθμίσεις εγγραφής" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Εγγραφή ροής:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain (ομαλοποίηση έντασης)" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Ενεργοποίηση ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Λειτουργία:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Αποτροπή αποκοπής (συνιστάται)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Διεύθυνση διαμεσολαβητή:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Θύρα διαμεσολαβητή:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Όνομα χρήστη διαμεσολαβητή:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Κωδικός πρόσβασης διαμεσολαβητή:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Ρυθμίσεις δικτύου" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Ρύθμιση διαμεσολαβητή" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Χρήση διαμεσολαβητή" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Χρήση πιστοποίησης με το διαμεσολαβητή" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Χρήση διαμεσολαβητή SOCKS" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Αυτόματη αναγνώριση κωδικοσελίδας για:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Εναλλακτικές κωδικοποιήσεις χαρακτήρων:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Συμπεριφορά" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Συνέχιση της αναπαραγωγής με την εκκίνηση" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Παύση αντί για άμεση επανάληψη" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Όταν το τρέχων αρχείο διαγράφεται, συνέχεια με το επόμενο" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Όταν ανοίγουν αρχεία, καθαρισμός της λίστας αναπαραγωγής" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Άνοιγμα αρχείων σε μια προσωρινή λίστα αναπαραγωγής" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Εμφάνιση" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Εμφάνιση αριθμών στα τραγούδια" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Εμφάνιση μηδενικών στην αρχή (02:00 αντί 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Εμφάνιση της ώρας ξεχωριστά (1:30:00 αντί 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Εξαγωγή" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Χρήση των αντίστοιχων διαδρομών, όταν είναι δυνατόν" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Άλμπουμ" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Αναζήτηση εικόνων που ταιριάζουν με τις λέξεις (διαχωρισμένες με κόμμα):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Εξαίρεση εικόνων που ταιριάζουν με τις λέξεις (διαχωρισμένες με κόμμα):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Αναζήτηση εικόνων που ταιριάζουν με το όνομα αρχείου του τραγουδιού" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Αναδρομική αναζήτηση" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Βάθος αναζήτησης:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Αναδυόμενες πληροφορίες" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Εμφάνιση πληροφοριών στο αναδυόμενο παράθυρο" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Καθυστέρηση (σε δέκατα του δευτερολέπτου):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Εμφάνιση χρονοδιαγράμματος για το τρέχον τραγούδι" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Συμβατότητα" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Σήμανση με \\\\ (αντιπλάγια μπάρα) ως διαχωριστικό φακέλων" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Λίστα αναπαραγωγής" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Αναδρομική προσθήκη φακέλων" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Προσθήκη φακέλων που περιέχουν τα αρχεία της λίστας αναπαραγωγής" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Μεταδεδομένα" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Υποθετικός υπολογισμός μεταδεδομένων που λείπουν από τη διαδρομή του αρχείου" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Να μη φορτώνονται μεταδεδομένα για τα τραγούδια μέχρι να παίξουν" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Διερεύνηση περιεχομένου αρχείων χωρίς αναγνωρισμένη επέκταση ονόματος" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Διάφορα" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Βήμα προς τα εμπρός/πίσω σε:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "δευτερόλεπτα" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Ρύθμιση έντασης σε:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "επί τοις εκατό" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "ΤΙΤΛΟΣ" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "ΤΙΤΛΟΣ - ΚΑΛΛΙΤΕΧΝΗΣ" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "ΤΙΤΛΟΣ - ΚΑΛΛΙΤΕΧΝΗΣ - ΑΛΜΠΟΥΜ" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ΚΑΛΛΙΤΕΧΝΗΣ - ΤΙΤΛΟΣ" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ΚΑΛΛΙΤΕΧΝΗΣ - ΑΛΜΠΟΥΜ - ΤΙΤΛΟΣ" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ΚΑΛΛΙΤΕΧΝΗΣ - ΑΛΜΠΟΥΜ - ΤΙΤΛΟΣ. ΤΡΑΓΟΥΔΙΟΥ" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ΚΑΛΛΙΤΕΧΝΗΣ [ ΑΛΜΠΟΥΜ ] - ΤΙΤΛΟΣ. ΤΡΑΓΟΥΔΙΟΥ" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ΑΛΜΠΟΥΜ - ΤΙΤΛΟΣ" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Κατηγορία" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Προσαρμοσμένο" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Μορφή τίτλου:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Προσαρμοσμένο αλφαριθμητικό:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Ενεργοποίηση εγγραφής ηχητικής ροής με το %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Δεν είναι διαθέσιμο κανένα πρόσθετο εγγραφής ήχου" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Ρυθμίσεις Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Άκυρο" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Αποθήκευση" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Φόρτωση" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Φόρτωση αρχείου προκαθορισμένων τιμών" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Φόρτωση αρχείου EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Αποθήκευση αρχείου προκαθορισμένων τιμών" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Αποθήκευση αρχείου EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Διαχειριστής σειράς αναμονής" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "Α_φαίρεση από την σειρά" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Εργασία..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Σφάλμα" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Πληροφόρηση" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Αποθήκευση" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Άνοιγμα διεύθυνσης URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Προσθήκη διεύθυνσης URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "_Καθαρισμός ιστορικού" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Εισαγωγή URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Άνοιγμα" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Έχουν κρυφτεί τα περαιτέρω μηνύματα.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Προεπιλεγμένα αρχεία (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Κλείσιμο" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Περιήγηση" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Άνοιγμα φακέλου" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Προσθήκη φακέλου" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Προσθήκη" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Επιλογή γραμματοσειράς" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Μετα-πληροφορίες" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Συνθέτης" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Ερμηνευτής" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Έτος εγγραφής" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Ημερομηνία εγγραφής" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Τεχνικά" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Ρυθμός διαμεταγωγής" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "MusicBrainz ID" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Επαναφορά" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Σφάλμα εγγραφής tag(s)." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 επιλεγμένα αρχεία" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "_Αποθήκευση %1 αρχείων" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Επίπεδο" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Λειτουργία" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Μήνυμα" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Καταγραφές" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Εντοπισμός σφαλμάτων" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Πληροφορίες" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Προειδοποίηση" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Κα_θαρισμός" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Επίπεδο καταγραφής:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Υπηρεσίες" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Αντιγραφή" diff --git a/po/en@boldquot.header b/po/en@boldquot.header new file mode 100644 index 0000000..fedb6a0 --- /dev/null +++ b/po/en@boldquot.header @@ -0,0 +1,25 @@ +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# +# This catalog furthermore displays the text between the quotation marks in +# bold face, assuming the VT100/XTerm escape sequences. +# diff --git a/po/en@quot.header b/po/en@quot.header new file mode 100644 index 0000000..a9647fc --- /dev/null +++ b/po/en@quot.header @@ -0,0 +1,22 @@ +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# diff --git a/po/en_GB.po b/po/en_GB.po new file mode 100644 index 0000000..25a8a10 --- /dev/null +++ b/po/en_GB.po @@ -0,0 +1,1502 @@ +# English (United Kingdom) translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Andi Chandler , 2013,2015-2018 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Andi Chandler \n" +"Language-Team: English (United Kingdom) (http://www.transifex.com/audacious/audacious/language/en_GB/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en_GB\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Show command-line help" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Show version" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Start playback" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pause playback" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pause if playing, play otherwise" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Stop playback" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Skip to previous song" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Skip to next song" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Add files to the playlist" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Add files to a temporary playlist" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Display the main window" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Display the jump-to-song window" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Start without a graphical interface" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Quit on playback stop" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Print debugging messages (may be used twice)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Unknown option: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Unknown option: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Usage: audacious [OPTION] ... [FILE] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Select instance to run/control" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d file found" +msgstr[1] "%d files found" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Error reading %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "No files found." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "New Playlist" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Standard input" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Audio CD, track %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(character encoding error)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Stream recording must be configured in Audio Settings before it can be used." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Error opening output stream" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Error recording output stream" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Error playing %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Invalid audio format" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Now Playing" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Error opening %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Error loading %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Cannot load %s: unsupported file name extension." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Cannot save %s: unsupported file name extension." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Error loading plugin" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Seek error" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "File format not recognised" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Error reading metadata" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d channel" +msgstr[1] "%d channels" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Audio CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Track %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(unknown title)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Unknown URI scheme" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Invalid file name" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Invalid access mode" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Credits" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licence" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "About Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Cancel" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Don’t ask again" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Do you want to permanently remove “%s”?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Remove" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Remove Playlist" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "What would you like to call this playlist?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Rename" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Rename Playlist" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Preset File ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF File ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Import" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Export" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Equaliser Presets" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Save Preset" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Delete Selected" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Revert Changes" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Enable" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Equaliser" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Presets ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Reset to Zero" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamp" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Open Files" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Open" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Close _dialogue on open" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Add Files" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Add" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Close _dialogue on add" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Close" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Title" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artist" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Genre" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Year" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Track" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Length" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Format:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Quality:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bitrate:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Chamber Music" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Classical" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Save successful" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Save error" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Song Info" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Album Artist" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Comment" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Track Number" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Save" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Next" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/A" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Jump" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Jump to Time" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Enter time (minutes:seconds):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Queue" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Un_queue" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Jump to Song" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filter: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filter:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "C_lose on jump" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Overwrite" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Confirm Overwrite" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Overwrite %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Please type a filename extension or select a format from the drop-down list." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Select Format by Extension" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Export Playlist" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Export" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Import Playlist" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Import" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Plugins ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "About %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Settings" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Set" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Settings" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_About" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Choose File" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Choose Folder" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Appearance" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Audio" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Network" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Playlist" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Plug-ins" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Advanced" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "General" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Effect" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualisation" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Input" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transport" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Album artist" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Track number" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "File name" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "File path" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Date" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Codec" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Quality" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "None" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arabic" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltic" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Chinese" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Greek" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebrew" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japanese" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Korean" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polish" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Russian" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanese" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turkish" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automatic" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Floating point" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "As decoded" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "After applying ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "After applying effects" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "After applying equalisation" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Based on shuffle" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interface:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Output plug-in:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Amplify all files:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Amplify untagged files:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Output Settings" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bit depth:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Buffer size:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Soft clipping" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Use software volume control (not recommended)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Recording Settings" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Record stream:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Enable ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Mode:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Prevent clipping (recommended)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Proxy hostname:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Proxy port:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Proxy username:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Proxy password:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Network Settings" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Proxy Configuration" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Enable proxy usage" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Use authentication with proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Auto character encoding detector for:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Fallback character encodings:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Behaviour" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Resume playback on startup" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pause instead of resuming immediately" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Advance when the current song is deleted" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Clear the playlist when opening files" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Open files in a temporary playlist" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Song Display" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Show song numbers" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Show leading zeroes (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Show hours separately (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Export" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Use relative paths when possible" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Album Art" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Search for images matching these words (comma-separated):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Exclude images matching these words (comma-separated):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Search for images matching song file name" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Search recursively" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Search depth:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Popup Information" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Show pop-up information" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Pop-up delay (tenths of a second):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Show time scale for current song" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Compatibility" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpret \\ (backward slash) as a folder delimiter" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Playlist" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Add folders recursively" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Add folders nested within playlist files" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadata" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Guess missing metadata from file path" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Do not load metadata for songs until played" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Probe content of files with no recognized file name extension" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Miscellaneous" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "seconds" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TITLE" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TITLE - ARTIST" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TITLE - ARTIST - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTIST - TITLE" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTIST - ALBUM - TITLE" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTIST - ALBUM - TRACK. TITLE" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTIST [ ALBUM ] - TRACK. TITLE" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - TITLE" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Category" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Custom" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Title format:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Custom string:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Enable audio stream recording with %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "No audio recording plugin available" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious Settings" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Cancel" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Save" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Load" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Load Preset File" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Load EQF File" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Save Preset File" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Save EQF File" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Queue Manager" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Unqueue" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Working ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Error" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Information" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Save to history" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Open URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Add URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "C_lear history" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Enter URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Open" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Further messages have been hidden.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Browse" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Open Folder" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Add Folder" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Add" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadata" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Composer" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Performer" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Recording Year" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Recording Date" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Technical" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bitrate" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Level" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Function" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Message" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Log Inspector" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Debug" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Info" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Warning" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Cl_ear" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Log Level:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Services" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Copy" diff --git a/po/es.po b/po/es.po new file mode 100644 index 0000000..7190675 --- /dev/null +++ b/po/es.po @@ -0,0 +1,1526 @@ +# Spanish translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Adolfo Jayme Barrientos , 2013-2014 +# Adolfo Jayme-Barrientos, 2013 +# Adolfo Jayme-Barrientos, 2016 +# Adolfo Jayme-Barrientos, 2015 +# Adolfo Jayme-Barrientos, 2013 +# Adrián Ramirez Escalante , 2012 +# Cosme Domínguez Díaz , 2010 +# enjolras , 2012 +# Francisco Javier F. Serrador , 2004 +# Guille Vicente , 2016 +# Gustavo D. Vranjes , 2006 +# Jeki Sinneo Leinos , 2008 +# Jordi Amenós <>, 2011 +# Jorge Andrés , 2010 +# Juan Manuel Hernández, 2012 +# fgp , 2016 +# Lucía Balsa , 2012 +# Marco Antonio Frias Butrón , 2012 +# Marco Antonio Frias Butrón , 2012 +# Marcos , 2013 +# Toni Estévez , 2019-2020 +# xukosky , 2011 +# xukosky , 2011 +# xukosky , 2011 +# enjolras , 2012 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 16:07+0000\n" +"Last-Translator: Toni Estévez \n" +"Language-Team: Spanish (http://www.transifex.com/audacious/audacious/language/es/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: es\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Mostrar la ayuda de la línea de órdenes" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Mostrar la versión" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Iniciar la reproducción" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pausar la reproducción" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pausar si se está reproduciendo o reproducir en caso contrario" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Detener la reproducción" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Ir a la canción anterior" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Ir a la canción siguiente" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Añadir archivos a la lista de reproducción" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Añadir archivos a una lista de reproducción temporal" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Mostrar la ventana principal" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Mostrar la ventana para saltar a una canción" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Iniciar sin una interfaz gráfica" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Salir al detener la reproducción" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Mostrar mensajes de depuración (puede usarse dos veces)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Ejecutar en modo GTK" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Opción desconocida: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Opción desconocida: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Uso: audacious [OPCIÓN] ... [ARCHIVO] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Seleccionar la instancia para ejecutar/controlar" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Se han encontrado %d archivo" +msgstr[1] "Se han encontrado %d archivos" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Error al leer %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "No se han encontrado ningún archivo." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Lista de reproducción nueva" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Entrada estándar" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "CD de audio, pista %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(error de codificación de caracteres)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Antes de poder usar la grabación de la transmisión, debe configurarse en los ajustes del audio." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Error al abrir la transmisión de salida" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Error en la grabación de la transmisión de salida" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Error al reproducir %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "El formato de audio no es válido" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "En reproducción" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Error al abrir %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Error al cargar %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "No se puede cargar %s: la extensión de archivo no es compatible." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Error al guardar %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "No se puede guardar %s: la extensión de archivo no es compatible." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Error al cargar el complemento" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Error de búsqueda" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "No se reconoce el formato del archivo" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Error al leer los metadatos" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Monoaural" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Estéreo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d canal" +msgstr[1] "%d canales" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "CD de audio" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Pista %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(título desconocido)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Esquema de URI desconocido" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "El nombre del archivo no es válido" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Modo de acceso no válido" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Créditos" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licencia" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Acerca de Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Cancelar" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_No preguntar de nuevo" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "¿Quiere eliminar permanentemente «%s»?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Eliminar" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Eliminar la lista de reproducción" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "¿Qué nombre quiere darle a esta lista?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Renombrar" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Renombrar la lista de reproducción" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Seleccione un perfil para exportar." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Archivo de preajustes..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Archivo EQF..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importar" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Preajustes del ecualizador" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Guardar preajustes" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Eliminar entradas seleccionadas" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Revertir cambios" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Activar" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Ecualizador" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Preajustes..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Restablecer a cero" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamplificación" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Abrir archivos" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Abrir" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Cerrar el _diálogo al abrir" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Añadir archivos" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Añadir" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Cerrar el _diálogo al añadir" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Cerrar" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Título" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artista" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Álbum" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Género" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Año" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Pista" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Duración" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formato:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Calidad:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Tasa de bits:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Música de cámara" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Clásica" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Guardado correctamente" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Error al guardar" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Información de la canción" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Artista del álbum" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Comentario" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Número de pista" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "Rellenar _automáticamente los campos vacíos" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Guardar" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Anterior" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Siguiente" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/D" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Saltar" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Saltar al instante" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Introducir el instante (minutos: segundos):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Añadir a la cola" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "_Quitar de la cola" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Saltar a la canción" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtro: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtro:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "C_errar al saltar" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Sobrescribir" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Confirmar la sobrescritura" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "¿Sobrescribir %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Escriba una extensión para el nombre del archivo o elija un formato de la lista." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Seleccionar el formato por la extensión" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Exportar la lista de reproducción" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "E_xportar" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importar la lista de reproducción" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importar" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "Com_plementos…" + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Acerca de %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Ajustes de %s" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Aplicar" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "Ajuste_s" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Acerca de" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Elija un archivo" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Elija una carpeta" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Apariencia" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Audio" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Red" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Lista de reproducción" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Complementos" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Avanzados" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "General" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efecto" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualización" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Entrada" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transporte" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Artista del álbum" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Número de pista" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nombre del archivo" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Ruta del archivo" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Fecha" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Descripción" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Códec" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Calidad" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Ninguno" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Árabe" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Báltico" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Chino" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Griego" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebreo" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japonés" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Coreano" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polaco" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Ruso" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanés" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turco" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automática" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Coma flotante" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Tal como ha sido descodificado" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Después de aplicar ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Después de aplicar los efectos" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Después de aplicar la ecualización" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Orden aleatorio" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interfaz:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Complemento de salida:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Amplificar todos los archivos:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Amplificar archivos sin etiqueta:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Ajustes de la salida" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Profundidad de bits:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Tamaño del búfer:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Recorte suave (mejora el audio sobreamplificado)" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Usar el control de volumen por software (no recomendado)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Ajustes de la grabación" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Grabar la transmisión:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Activar ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Modo:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Evitar el recorte (recomendado)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Nombre del servidor proxy:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Puerto del proxy:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Nombre del usuario del proxy:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Contraseña del proxy:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Ajustes de la red" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Configuración del proxy" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Activar uso del proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Usar autenticación con el proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Usar proxy SOCKS" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Detector automático de la codificación de caracteres para: " + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Codificación de caracteres alternativa:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Comportamiento" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Reanudar la reproducción al inicio" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pausar en lugar de reanudar inmediatamente" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Avanzar cuando se borra la canción actual" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Borrar la lista de reproducción al abrir archivos" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Abrir archivos en una lista de reproducción temporal" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Visualización de las canciones" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Mostrar el número de las canciones" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Mostrar los ceros a la izquierda (02:00 en vez de 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Mostrar las horas separadamente (1:30:00 en vez de 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Usar rutas relativas cuando sea posible" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Carátula del álbum" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Buscar imágenes que se correspondan con estas palabras (separadas por comas):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Excluir imágenes que se correspondan con estas palabras (separadas por comas):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Buscar imágenes que se correspondan con el nombre del archivo de la canción" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Buscar recursivamente" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Profundidad de la búsqueda:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Información emergente" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Mostrar información emergente" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Retardo en la aparición (décimas de segundo):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Mostrar una barra de tiempo para la canción actual" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Compatibilidad" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpretar el carácter «\\» (barra invertida) como separador de carpetas" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Lista de reproducción" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Añadir carpetas recursivamente" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Añadir carpetas anidadas en los archivos de lista de reproducción" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadatos" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Deducir los metadatos que faltan a partir de ruta del archivo" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "No cargar los metadatos de las canciones hasta que se reproduzcan" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Examinar el contenido de los archivos con una extensión no reconocida" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Miscelánea" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Paso adelante/atrás:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "segundos" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Ajustar el volumen:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "por ciento" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TÍTULO" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TÍTULO - ARTISTA" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TÍTULO - ARTISTA - ÁLBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTISTA - TÍTULO" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTISTA - ÁLBUM - TÍTULO" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTISTA - ÁLBUM - PISTA. TÍTULO" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTISTA [ ÁLBUM ] - PISTA. TÍTULO" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ÁLBUM - TÍTULO" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Categoría" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Personalizado" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Formato del título:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Cadena personalizada:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Activar la grabación de la transmisión de audio con %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "No hay disponible ningún complemento de grabación de audio" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Ajustes de Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Cancelar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Guardar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Cargar" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Cargar un archivo de preajustes" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Cargar un archivo EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Guardar el archivo de preajustes" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Guardar el archivo EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Gestor de la cola" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Quitar de la cola" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Trabajando…" + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Error" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Información" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Guardar en el historial" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Abrir una URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Añadir una URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "_Borrar el historial" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Introducir el URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Abrir" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Se han ocultado el resto de mensajes.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Archivos de perfil (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Cerrar" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Examinar" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Abrir una carpeta" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Añadir una carpeta" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Añadir" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Configurar la tipografía" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadatos" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Compositor" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Intérprete" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Año de grabación" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Fecha de grabación" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Datos técnicos" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Tasa de bits" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "ID de MusicBrainz" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Revertir" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Error al escribir las etiquetas." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 archivos seleccionados" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "_Guardar %1 archivos" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Nivel" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Función" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Mensaje" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Inspector de registros" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Depuración" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Información" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Advertencia" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "_Borrar" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Nivel de registro:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Servicios" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Copiar" diff --git a/po/es_AR.po b/po/es_AR.po new file mode 100644 index 0000000..0d0cdb5 --- /dev/null +++ b/po/es_AR.po @@ -0,0 +1,1512 @@ +# Spanish (Argentinian) translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Adrián Ramirez Escalante , 2012-2013 +# Cosme Domínguez Díaz , 2010 +# Francisco Javier F. Serrador , 2004 +# Gustavo D. Vranjes , 2006 +# Jeki Sinneo Leinos , 2008 +# Jordi Amenós <>, 2011 +# Jorge Andrés , 2010 +# Rodolfo , 2017 +# Rodolfo , 2019 +# xukosky , 2011 +# xukosky , 2011 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Adrián Ramirez Escalante \n" +"Language-Team: Spanish (Argentina) (http://www.transifex.com/audacious/audacious/language/es_AR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: es_AR\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Mostrar ayuda para línea de comandos" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Mostrar versión" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Comenzar reproducción" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pausar reproducción" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pausar si se está reproduciendo, o reproducir" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Detener reproducción" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Saltar a canción previa" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Saltar a siguiente canción" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Añadir archivos a la lista de reproducción" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Agregar archivos a lista de reproducción temporal" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Mostrar la ventana principal" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Mostrar la ventana de salto-a-canción" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Arrancar sin interface gráfica" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Salir al detener la reproducción" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Imprimir mensajes de depuración (puede ser usado dos veces)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Opción desconocida: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Opción desconocida: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Uso: audacious [OPTION] ... [FILE] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Seleccionar instancia para correr/controlar" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d archivo encontrado" +msgstr[1] "%d archivos encontrados" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Error leyendo %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "No se encontraron archivos." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nueva lista de reproducción" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Entrada estandard" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "CD de audio, pista %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(error de codificación de caracter)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Grabación del flujo debe ser configurada en Opciones de Audio antes de ser usada." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Error abriendo flujo de salida" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Error grabando flujo de salida" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Error reproduciendo %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Formato de audio inválido" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Reproducción actual" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Error abriendo %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Error leyendo %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "No puedo leer %s: extensión de archivo no soportada." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "No puedo salvar %s: extensión de archivo no soportada." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Error leyendo plugin" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Error de búsqueda" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Formato de archivo no reconocido" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Error leyendo metadatos" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Estéreo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d canal" +msgstr[1] "%d canales" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "CD de audio" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Pista %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(título desconocido)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Esquema de URI desconocido" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Nombre de archivo inválido" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Modo de acceso inválido" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Créditos:" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licencia" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Acerca de Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Cancelar" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_No volver a preguntar" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "¿Querés eliminar \"%s\" permanentemente?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Remover" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Remover Lista de temas" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "¿Cómo querés llamar a esta lista de temas?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Renombrar" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Renombrar la lista de reproducción" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Archivo Preseteado ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Archivo EQF ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importar" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Preseteos de Ecualizador" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Grabar Preseteo" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Borrar Seleccionado" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Revertir Cambios" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Activar" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Ecualizador" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Preseteos ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Reponer a Zero" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamplificación" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Abrir archivos" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Abrir" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Cerrar _diálogo al abrir" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Añadir archivos..." + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Agregar" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Cerrar _diálogo al agregar" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Cerrar" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Título" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artista" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Álbum" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Género" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Año" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Pista" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Duración" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formato:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Calidad:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Muestreo de bits:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Jazz ácido" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Rock ácido" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambiental" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Música de cámara" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Clásica" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folclore" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Rock Punk" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Satisfactoriamente guardado" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Error en guardado" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Información de la canción" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Artista del Album" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Comentario" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Número de pista" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Salvar" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "Si_guiente" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/D" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Saltar" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Ir a tiempo" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Ingresar tiempo (minutos:segundos):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Cola" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "_Remover de la cola" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Ir a una canción" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtro: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtro:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "C_errar al saltar" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Sobreescribir" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Confirmá Sobreescritura" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "¿Sobrescribir %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Por favor escribí una extensión de archivo o seleccioná un formato de la lista desplegable." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Seleccioná el Formato por Extensión" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Exportar lista de reproducción" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exportar" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importar lista de reproducción" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importar" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Plugins ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Acerca de %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Configuración" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Setear" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Opciones" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Sobre" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Elegir Archivo" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Elija una carpeta" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Apariencia" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Audio" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Red" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Lista de reproducción" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Complementos" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Avanzado" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "General" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efecto" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualización" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Entrada" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transporte" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Artista del Album" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Número de Pista" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nombre del archivo" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Ruta del archivo" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Fecha" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Codec (formato)" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Calidad" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Ninguno" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arábico" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Báltico" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Chino" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Griego" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebreo" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japonés" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Coreano" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polaco" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Ruso" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanés" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turco" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automático" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Coma flotante" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Como decodificado" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Después de aplicar ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Después de aplicar efectos" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Después de aplicar ecualizació" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Basado en shuffle" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interface:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Complemento de salida:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Amplificar todos los archivos:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Amplificar archivos sin etiqueta:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Ajustes de salida" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Profundidad de bit:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Tamaño del búfer:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Detener saltos" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Usar control de volumen por software (no recomendado)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Opciones de Grabación" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Grabar flujos:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Activar ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Modo:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Evitar cortes (recomendado)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Servidor proxy:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Puerto del proxy:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Nombre de usuario del proxy:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Contraseña del proxy:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Opciones de Red" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Configuración del Proxy" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Activar uso del proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Usar autenticación con el proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Detector de codificación de caracteres automático para: " + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Codificación de caracteres alternativa:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Comportamiento" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Restaurar reproducción al arrancar" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pausar en vez de continuar inmediatamente" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Avanzar cuando se borra la canción actual" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Limpiar la lista de reproducción al abrir archivos" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Abrir archivos en una lista de reproducción temporal" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Visualización de las canciones" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Mostrar números de las canciones" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Mostrar ceros antepuestos (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Mostrar horas separadamente (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Usar rutas relativas cuando sea posible" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Arte de tapa" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Buscar imágenes correspondientes a estas palabras clave (separadas por comas):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Excluir imágenes correspondientes a estas palabras clave (separadas por comas):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Buscar imágeness coincidiendo con nombres de canciones " + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Buscar recursivamente" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Búsqueda profunda" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Información emergente" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Mostrar información emergente" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Retardo en mensajes emergentes (décimas de segundo):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Mostrar línea de tiempo para la canción actual" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Compatibilidad" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Intérprete \\ (barra invertida) como un delimitador de carpeta" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Lista de temas" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Agregar carpetas recursivamente" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Agregar carpetas anidadas dentro de archivos de lista de temas" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadatos" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Adivinar metadatos faltantes a partir de la ruta de archivo" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "No cargar la información de metadatos hasta reproducir" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Probar contenido de archivos al no reconocer la extensión" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Varios" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "segundos" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TÍTULO" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TITULO - ARTISTA" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TITULO - ARTISTA - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTISTA - TÍTULO" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTISTA - ÁLBUM - TÍTULO" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTISTA - ÁLBUM - PISTA. TÍTULO" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTISTA [ ÁLBUM ] - PISTA. TÍTULO" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ÁLBUM - TÍTULO" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Categoría" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Personalizada" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Formato del título:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Cadena personalizada:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Activar la grabación de flujo de audio con %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "No hay plugin de grabación de audio disponible" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Opciones de Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Cancelar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Guardar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Cargar" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Leer Archivo de Preseteo" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Leer Archivo EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Grabar archivo de Preseteo" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Salvar archivo EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Gestor de cola de reproducción" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Desencolar" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Trabajando .." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Error" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Información" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Guardar historial" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Abrir URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Añadir URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "B_orrar historial" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Ingresar URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Abrir" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Se han ocultado el resto de mensajes.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Cerrar" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Examinar" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Abrir Carpeta" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Agregar Carpeta" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Agregar" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadatos" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Compositor" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Intérprete" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Año de Grabación" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Fecha de Grabación" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Técnico" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Tasa de bits" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Nivel" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Función" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Mensaje" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Inspector de Registro" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Depuración" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Info" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Cuidado" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Limp_iar" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Nivel de registro:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Servicios" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Copiar" diff --git a/po/es_MX.po b/po/es_MX.po new file mode 100644 index 0000000..f4ba922 --- /dev/null +++ b/po/es_MX.po @@ -0,0 +1,1504 @@ +# Spanish (Mexican) translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Jorge A. García Sosa , 2012-2014 +# Jorge A. García Sosa , 2014-2017,2019 +# Severiano Jaramillo Quintanar, 2015 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Jorge A. García Sosa \n" +"Language-Team: Spanish (Mexico) (http://www.transifex.com/audacious/audacious/language/es_MX/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: es_MX\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Mostrar ayuda de línea de comando" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Mostrar versión" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Iniciar reproducción" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pausar reproducción" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pausar si está reproduciendo; de lo contrario, reproducir" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Detener reproducción" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Regresar a la pista anterior" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Saltar a la siguiente pista" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Agregar archivos a la lista de reproducción" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Agregar archivos a la lista de reproducción temporal" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Mostrar la ventana principal" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Mostrar la ventana saltar-a-la-pista" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Iniciar sin una interfaz gráfica" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Quitar al detener reproducción" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Imprimir mensajes de depuración (puede ser usado dos veces)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Opción desconocida: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Opción desconocida: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Uso: audacious [OPCIÓN] ... [ARCHIVO] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Seleccionar instancia para ejecutar/controlar" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d archivo encontrado" +msgstr[1] "%d archivos encontrados" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Error al leer %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "No se encontraron archivos." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nueva Lista de reproducción" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Entrada estándar" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "CD de Audio, pista %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(error de codificación de caracteres)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "La grabación de stream debe ser configurada en Preferencias de Audio antes de que pueda ser usado." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Error al abrir stream de salida" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Error en la grabación del stream de salida" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Error al reproducir %s\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Formato de audio invalido" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Reproduciendo" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Error al abrir %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Error al cargar %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "No se pudo cargar %s: extensión de archivo no soportada." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "No se pudo guardar %s: extensión de archivo no soportada." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Error al cargar plugin" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Error de búsqueda" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Formato de archivo no reconocido" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Error al leer metadatos" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Monoaural" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Estéreo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d canal" +msgstr[1] "%d canales" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "CD de Audio" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Pista %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(título desconocido)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Esquema URI desconocido" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Nombre de archivo invalido" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Modo de acceso inválido" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Créditos" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licencia" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Acerca de Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Cancelar" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_No preguntar otra vez" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "¿Quieres remover permanentemente \"%s\"?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Remover" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Remover Lista de Reproducción" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "¿Te gustaría llamar esta lista de reproducción?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Renombrar" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Renombrar la Lista de Reproducción" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Archivo de Preajuste ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Archivo EQF ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importar" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Prejustes de Ecualizador" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Guardar Preajustes" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Borrar Seleccionado" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Revertir Cambios" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Habilitar" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Ecualizador" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Preajustes ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Resetear a Cero" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamplificador" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Abrir Archivos" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Abrir" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Cerrar _dialogo al abrir" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Agregar Archivos" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Agregar" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Cerrar _dialogo al agregar" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Cerrar" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Título" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artista" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Álbum" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Género" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Año" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Pista" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Duración" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formato:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Calidad:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Tasa de bits:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Música de Cámara" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Clásica" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Guardar exitósamente" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Error al guardar" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Información de Pista" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Artista del Álbum" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Comentario" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Número de Pista" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Guardar" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "Siguie_nte" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/D" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Saltar" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Saltar al Tiempo" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Ingresa el tiempo (minutos:segundos):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "A la _Cola" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Quitar de la _cola" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Saltar a la Pista" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtro: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtro:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Ce_rrar al saltar" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "S_obreescribir" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Confirmar Sobreescritura" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "¿Sobreescribir %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Por favor escribe una extensión de archivo o selecciona un formato de la lista." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Selecciona Formato por Extensión" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Exportar Lista de Reproducción" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exportar" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importar Lista de Reproducción" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importar" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Plugins ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Acerca %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Ajustes" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Ajuste" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Ajustes" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Acerca" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Elige Archivo" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Elige Carpeta" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Apariencia" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Audio" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Red" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Lista de Reproducción" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Plugins" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Avanzado" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "General" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efecto" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualización" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Entrada" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transporte" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Artista de Álbum" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Número de pista" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nombre de archivo" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Ruta de archivo" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Fecha" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Codec" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Calidad" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Ninguno" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Árabe" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Báltico" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Chino" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Griego" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebreo" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japonés" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Coreano" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polaco" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Ruso" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanés" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turco" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automático" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Punto flotante" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Como es descodificado" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Después de aplicar ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Después de aplicar efectos" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Después de aplicar ecualización" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Basado en aleatorio" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interface:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Plugin de Salida:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Amplificar todos los archivos:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Amplificar archivos sin etiquetas:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Ajustes de Salida" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Profundidad de bit:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Tamaño del Buffer:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Clipping suave" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Usar control de volumen por software (no recomendado)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Ajustes de Grabación" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Grabar stream:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Habilitar ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Modo:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Evitar distorsiones clip (recomendado)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Nombre del host proxy:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Puerto proxy:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "nombre de usuario proxy:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "contraseña proxy:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Ajustes de Red" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Configuración del Proxy" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Habilitar uso del proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Usar autenticación con el proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Detector automático de codificación de caracteres para:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Codificación de caracteres alternativa:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Comportamiento" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Reanudar reproducción al iniciar" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pausa en vez de reanudar inmediatamente" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Avanzar cuando la pista actual sea borrada" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Limpiar la lista de reproducción al abrir archivos" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Abrir archivos en una lista de reproducción temporal" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Visualización de Pista" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Mostrar números de pista" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Mostrar ceros al inicio (02:00 vs 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Mostrar horas separadas (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Usar rutas relativas cuando sea posible" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Portada de Álbum" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Buscar imágenes con éstas palabras (separadas por comas):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Excluir imágenes con éstas palabras (separadas por comas):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Buscar imágenes con el nombre del archivo" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Buscar recursívamente" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Profundidad de búsqueda:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Información Emergente" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Mostrar información emergente" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Retraso de emergente (décimas de segundo):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Mostrar escala de tiempo para la pista actual" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Compatibilidad" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpretar \\ (diagonal invertida) como un delimitador de carpetas" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Lista de repr." + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Agregar folders recursivamente" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Agregar folders anidados dentro de archivos de lista de repr." + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadatos" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Adivinar metadatos perdidos desde el destino del archivo" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "No cargar metadatos de pistas hasta su reproducción" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Probar contenido de archivos con extensión no reconocida" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Misceláneo" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "segundos" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TÍTULO" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TÍTULO - ARTISTA" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TÍTULO - ARTISTA - ÁLBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTISTA - TÍTULO" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTISTA - ÁLBUM - TÍTULO" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTISTA - ÁLBUM - PISTA. TÍTULO" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTISTA [ÁLBUM] - PISTA. TÍTULO" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ÁLBUM - TÍTULO" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Categoría" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Personalizar" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Formato de Título" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Cadena personalizada:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Habilitar grabación de stream de audio con %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Plugin de grabación de audio no disponible" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Ajustes de Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Cancelar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Guardar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Cargar" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Cargar Archivo de Preajustes" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Cargar Archivo EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Guargar Archvio de Preajustes" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Guardar Archivo EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Administrador de colas" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Quitar de la fila" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Trabajando ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Error" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Información" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Guardar en la historia" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Abrir URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Agregar URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "B_orrar historia" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Ingresa URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Abrir" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Más mensajes han sido ocultados.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Cerrar" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Examinar" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Abrir Carpeta" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Agregar carpeta" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Agregar" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadatos" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Compositor" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Intérprete" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Año de Grabación" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Fecha de Grabación" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Técnico" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Tasa de bit" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Nivel" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Función" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Mensaje" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Inspector de Registro" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Depurar" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Info" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Advertencia" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "L_impiar" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Nivel de Registro:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Servicios" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Copiar" diff --git a/po/et.po b/po/et.po new file mode 100644 index 0000000..913d06d --- /dev/null +++ b/po/et.po @@ -0,0 +1,1505 @@ +# Estonian translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Ivar Smolin , 2007 +# Ivar Smolin , 2012-2013,2017-2020 +# John Lindgren , 2012 +# John Lindgren , 2012 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: John Lindgren \n" +"Language-Team: Estonian (http://www.transifex.com/audacious/audacious/language/et/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: et\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Käsurea abiteabe näitamine" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Versiooni näitamine" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Esituse kävitamine" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Esituse pausimine" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Esitamise korral pausimine, pausi korral esitamine" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Esituse seiskamine" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Hüppamine eelmisele loole" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Hüppamine järgmisele loole" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Failide lisamine esitusnimekirja" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Failide lisamine ajutisse esitusnimekirja" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Peaakna kuvamine" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Loole hüppamise akna kuvamine" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Käivitamine ilma graafilise liideseta" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Programmi sulgemine esituse lõppedes" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Silumisteadete väljastamine (võimalik topletkasutada)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Tundmatu võti: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Tundmatu võti: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Kasutamine: audacious [VÕTI] ... [FAIL] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Käivitatava/juhitava isendi valimine" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "leiti %d fail" +msgstr[1] "leiti %d faili" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Viga %s lugemisel:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Faile ei leitud." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Uus esitusnimekiri" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Standardsisend" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Audio-CD, lugu %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(märgikodeeringu viga)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Enne kasutamist tuleb voo salvestamine seadistada, seda saab teha audiosätete alt." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Viga väljundvoo avamisel" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Viga väljundvoo salvestamisel" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Viga %s esitamisel:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Vigane audiovorming" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Praegu esitamisel" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Viga %s avamisel:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Viga %s laadimisel." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Faili %s laadimine pole võimalik: failinime laiend pole toetatud." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Faili %s salvestamine pole võimalik: failinime laiend pole toetatud." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Viga plugina laadimisel" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Tuvastamatu failivorming" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Viga metaandmete lugemisel" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanal" +msgstr[1] "%d kanalit" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Audio CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Rada %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(tundmatu pealkiri)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Vigane URI skeem" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Vigane failinimi" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Autorid" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Litsents" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Audacious'est lähemalt" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "Tü_hista" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "Tulevikus rohkem ei _küsita" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Kas eemaldada \"%s\" jäädavalt?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Eemalda" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Esitusnimekirja eemaldamine" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Mis nime sa soovid sellele esitusnimekirjale anda?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Muuda nime" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Esitusnimekirja nime muutmine" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Eelsätete fail..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF-fail .." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Import" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Eksport" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Ekvalaiseri eelsätted" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Salvesta eelsätted" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Kustuta valik" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Võta muutused tagasi" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Lubatud" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Ekvalaiser" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Eelsätted..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Nulli" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Eelmoonutus" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Failide avamine" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Ava" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Avamise järel _dialoog suletakse" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Failide lisamine" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Lisa" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Lisamise järel _dialoog suletakse" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "Sul_ge" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Pealkiri" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Esitaja" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Žanr" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Aasta" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Rada" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Kestus" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Vorming:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Kvaliteet:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bitikiirus:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Bluus" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Kammermuusika" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klassikaline" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Kantri" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disko" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Ajaviitemuusika" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Raske rokk" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Džäss" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Müra" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punkrokk" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Räpp" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Rege" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rokk" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock & Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rütmibluus" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Sving" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Tehno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Salvestamine oli edukas" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Viga salvestamisel" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Loo andmed" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Albumi esitaja" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Kommentaar" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Raja number" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Salvesta" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Järgmine" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Ajahetkele hüppamine" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Sisesta aeg (minutid:sekundid):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "Pane _järjekorda" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Eemalda _järjekorrast" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Loo vahetamine" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filter: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filter:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Kirjuta üle" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Ülekirjutamise kinnitus" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Kas kirjutada fail %s üle?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Palun sisesta failinime laiend või vali vorming valikunimekirjast." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Vorming valitakse laiendi järgi" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Esitusnimekirja eksportimine" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Esitusnimekirja importimine" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Pluginad ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "%s ‒ plugina andmed" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s - sätted" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Määra" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Sätted" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Faili valimine" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Kataloogi valimine" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Välimus" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Audio" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Võrk" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Esitusnimekiri" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Pluginad" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Üldine" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efekt" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualiseerimine" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Sisend" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transport" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Albumi esitaja" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Raja number" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Fail nimi" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Faili rada" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Kuupäev" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Koodek" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Kvaliteet" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Puudub" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Araabia" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Balti" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Hiina" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Kreeka" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Heebrea" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Jaapani" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Korea" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Poola" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Vene" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taivani" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Türgi" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automaatne" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Ujukoma" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Pärast dekoodimist" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Pärast ReplayGain'i rakendamist" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Pärast efektide rakendamist" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Pärast ekvalaiseri rakendamist" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Liides:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Väljundplugin:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Kõikide failide võimendamine:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Sildistamata failide võimendamine:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Väljundi sätted" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bitisügavus:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Puhvri suurus:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Pehme kärpimine" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Tarkvaraline valjuse juhtimine (pole soovitatav)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Salvestamise sätted" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Voo salvestamine:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Režiim:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Hoidutakse kärpimisest (soovitatav)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Proksi hostinimi:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Proksi port:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Proksi kasutajanimi:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Proksi parool:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Võrgusätted" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Proksi sätted" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Proksi kasutamine on lubatud" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Proksi kasutatab autentimist" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automaatne kooditabeli tuvastaja:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Kooditabelite tagavara:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Käitumine" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Käivitamisel jätkatakse esitamist" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Kohese esitamise asemel määratakse paus" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Esitatava loo kustutamisel hakatakse järgmist lugu esitama" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Failide avamisel tühjendatakse esitusnimekiri" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Failid avatakse ajutises esitusnimekirjas" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Loo kuvamine" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Näidatakse lugude numbreid" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Näidatakse algusnulle (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Tunde näidatakse eraldi (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Albumite kujundused" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Otsitakse nende sõnadega kattuvaid pilte (komaga eraldatud nimekiri):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Nende nende sõnadega kattuvad pildid välistatakse (komaga eraldatud nimekiri):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Otsitakse loo failinimega kattuvaid pilte" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Otsing toimub sügavuti" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Otsingu sügavus:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Loo andmete hüpikaken" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Loo andmeid näidatakse hüpikaknas" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Lahtihüppamise viivitus (sekundikümnendikes):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Esitamisel oleva loo kohta näidatakse ajaskaalat" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Ühilduvus" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Märki \\ (kurakaldkriips) käsitletakse kataloogide eraldajana" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Esitusnimekiri" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metaandmed" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Puuduvad metaandmed tuletatakse faili rajast" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Loo metaandmeid enne esitamist ei laadita" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Tuvastamatu laiendiga failide puhul uuritakse faili sisu" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Muu" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "sekundit" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "PEALKIRI" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "PEALKIRI - ESITAJA" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "PEALKIRI - ESITAJA - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ESITAJA - PEALKIRI" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ESITAJA - ALBUM - PEALKIRI" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ESITAJA - ALBUM - RADA. PEALKIRI" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ESITAJA [ALBUM] - RADA. PEALKIRI" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - PEALKIRI" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategooria" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Kohandatud" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Pealkirja vorming:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Kohandatud string:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Audiosalvestamise pluginat pole saadaval" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audaciouse sätted" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Tühista" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Salvesta" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Laadi" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Eelsätete faili laadimine" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "EQF-faili laadimine" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Eelsätete faili salvestamine" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "EQF-faili salvestamine" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Esitusjärjekorra haldamine" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Töötamine ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Viga" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Teave" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "URL-i avamine" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "URL-i lisamine" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Sisesta URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Ava" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Ülejäänud sõnumid peidetakse.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Sulge" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Sirvi" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Ava kataloog" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Lisa kataloog" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Lisa" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metaandmed" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Helilooja" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Esitaja" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Salvestamise aasta" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Salvestamise kuupäev" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Tehniline" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bitikiirus" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Tase" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Funktsioon" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Sõnum" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Logiinspektor" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Silumine" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Info" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Hoiatus" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Logimise tase:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Teenused" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopeeri" diff --git a/po/fi.po b/po/fi.po new file mode 100644 index 0000000..6307a19 --- /dev/null +++ b/po/fi.po @@ -0,0 +1,1510 @@ +# Finnish translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Elias Julkunen , 2011 +# J. S. Tuomisto , 2013 +# Jiri Grönroos , 2014-2017,2019-2020 +# J. S. Tuomisto , 2013 +# J. S. Tuomisto , 2013 +# Kimmo Kujansuu , 2020 +# Matti Hämäläinen, 2008 +# Pauli Virtanen , 2004 +# Tuomas Lähteenmäki , 2012 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-05-07 17:08+0000\n" +"Last-Translator: Kimmo Kujansuu \n" +"Language-Team: Finnish (http://www.transifex.com/audacious/audacious/language/fi/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fi\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Näytä komentorivin ohje" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Näytä versio" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Aloita toisto" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Keskeytä toisto" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Keskeytä jos kappale soi, muutoin jatka soittamista" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Pysäytä toisto" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Siirry edelliseen kappaleeseen" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Siirry seuraavaan kappaleeseen" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Lisää tiedostoja soittolistaan" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Lisää tiedostoja väliaikaiselle soittolistalle" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Näytä pääikkuna" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Näytä \"siirry kappaleeseen\"-ikkuna" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Käynnistä ilman graafista käyttöliittymää" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Sulje kun toisto pysäytetään" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Tulosta vianjäljitysviestit (mahdollista käyttää kahdesti)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Suorita GTK-tilassa" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Tuntematon valinta: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Tuntematon valinta: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Käyttö: audacious [VALINTA] ... [TIEDOSTO] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Valitse suoritettava/hallittava esiintymä" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d tiedosto löytyi" +msgstr[1] "%d tiedostoa löytyi" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Virhe luettaessa %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Tiedostoja ei löytynyt." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Uusi soittolista" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Vakio sisääntulo" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Ääni-CD, kappale %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(merkistökoodausvirhe)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Suoratoiston tallennus on määritettävä ääniasetuksissa, ennen kuin sitä voidaan käyttää." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Virhe avattaessa suoratoiston ulostuloa" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Virhe tallennettaessa suoratoiston ulostuloa" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Virhe toistaessa %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Virheellinen äänimuoto" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Soi nyt" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Virhe avattaessa %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Virhe ladatessa %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Kohdetta %s ei voi ladata: tiedostopääte ei ole tuettu." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Virhe tallennettaessa %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Kohdetta %s ei voi tallentaa: tiedostopääte ei ole tuettu." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Virhe liitännäistä ladattaessa" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Siirtymisvirhe" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Tiedostomuotoa ei tunnistettu" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Virhe metatietoja luettaessa" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanava" +msgstr[1] "%d kanavaa" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Ääni-CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Kappale %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(tuntematon nimi)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Tuntematon URI-ohjelma" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Virheellinen tiedostonimi" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Virheellinen käyttötila" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Tekijät" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Lisenssi" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Tietoja Audaciouksesta" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Peru" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Älä kysy uudelleen" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Haluastko poistaa kohteen “%s” pysyvästi?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Poista" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Poista soittolista" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Minkä nimen haluat antaa tälle soittolistalle?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Nimeä uudelleen" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Nimeä soittolista uudelleen" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Valitse yksi tuotava esiasetus." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Esiasetustiedosto..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF-tiedosto..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Tuo" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Vie" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Taajuuskorjaimen esiasetukset" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Tallenna esiasetukset" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Poista valitut" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Kumoa muutokset" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Käytä" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Taajuuskorjain" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Esiasetukset..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Palauta nollaksi" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Esivahvistus" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Avaa tiedostoja" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Avaa" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "S_ulje ikkuna avatessa" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Lisää tiedostoja" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Lisää" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Sul_je ikkuna lisättäessä" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Sulje" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Nimi" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Esittäjä" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Albumi" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Tyylilaji" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Vuosi" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Kappale" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Kesto" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Muoto:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Laatu:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bittinopeus:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Kamarimusiikki" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klassinen" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Kantri" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disko" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Kevyt kuunneltava" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta-rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metalli" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock 'n' roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "R'n'B" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Tekno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Tallennus onnistui" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Virhe tallennettaessa" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Kappaleen tiedot" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Albumi / esittäjä" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Kommentti" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Kappaleen numero" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "_Täytä automaattisesti tyhjät kentät" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Tallenna" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Edellinen" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Seuraava" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "-" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "Sii_rry" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Hyppää aikaan" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Syötä aika (minuutit:sekunnit):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Lisää jonoon" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "_Poista jonosta" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Hyppää kappaleeseen" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Suodatin: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Suodatin:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "S_ulje siirryttäessä" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Korvaa" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Vahvista korvaaminen" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Ylikirjoita %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Valitse tiedostonimen pääte tai valitse muoto pudotusvalikosta." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Valitse muoto tiedostopäätteen avulla" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Vie soittolista" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Vie" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Tuo soittolista" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Tuo" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Liitännäiset..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Tietoja - %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s - asetukset" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Aseta" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Asetukset" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Tietoja" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Valitse tiedosto" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Valitse kansio" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Ulkoasu" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Ääni" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Verkko" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Soittolista" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Liitännäiset" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Lisäasetukset" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Yleiset" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Tehosteet" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualisoinnit" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Äänilähteet" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Siirtokanavat" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Albumin esittäjä" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Kappalenumero" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Tiedostonimi" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Tiedoston polku" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Päiväys" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Kuvaus" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Koodekki" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Laatu" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Ei mikään" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arabia" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Balttia" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Kiina" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Kreikka" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Heprea" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japani" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Korea" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Puola" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Venäjä" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwan" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turkki" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automaattinen" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Liukuluku" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Dekoodattuna" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Uudelleentoiston vahvistuksen jälkeen" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Efektien lisäyksen jälkeen" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Taajuuskorjauksen jälkeen" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Perustuu sekoitukseen" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Käyttöliittymä:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Ulostulon lisäosa:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Vahvista kaikki tiedostot:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Vahvista luokittelemattomat tiedostot:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Ulostulon asetukset" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bittisyvyys:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Puskurin koko:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Pehmeä leikkaantuminen" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Käytä ohjelmallista äänensäätöä (ei suositeltu)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Nauhoitusasetukset" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Tallenna suoratoisto:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Käytä ReplayGainia" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Tila:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Estä leikkaantuminen (suositeltu)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Välityspalvelimen osoite:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Välityspalvelimen portti:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Välityspalvelimen käyttäjätunnus:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Välityspalvelimen salasana:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Verkkoasetukset" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Välityspalvelimen asetukset" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Käytä välityspalvelinta" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Käytä tunnistautumista välityspalvelimen kanssa" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Käytä SOCKS-välityspalvelinta" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automaattinen merkistökoodauksen tunnistus:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Toissijaiset merkistökoodaukset:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Käytös" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Palauta toisto käynnistäessä" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Keskeytä välittömän palauttamisen sijaan" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Jatka, kun nykyinen kappale on poistettu" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Tyhjennä soittolista avattaessa tiedostoja" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Avaa tiedostot väliaikaisessa soittolistassa" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Kappaleen näyttö" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Näytä kappalenumerot" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Näytä etunollat (02:00 vrt. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Näytä tunnit erillisenä (1:30:00 vrt. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Vie" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Käytä suhteellisia polkuja kun mahdollista" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Albumikansi" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Etsi kuvia joissa esiintyy sanat (erota pilkulla):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Hylkää kuvat joissa esiintyy sanat (erota pilkulla):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Etsi kuvia jotka täsmäävät kappaleen tiedostonimeen" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Etsi rekursiivisesti" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Etsintäsyvyys:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Ponnahdusikkuna" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Näytä ponnahdusikkuna" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Ponnahdusikkunan viive (kymmenesosasekunti):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Näytä soivan kappaleen aikapalkki" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Yhteensopivuus" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Tulkitse \\ (kenoviiva) kansioerottimeksi" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Soittolista" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Lisää kansiot rekursiivisesti" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Lisää soittolistatiedostoihin sisäkkäisiä kansioita" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metatiedot" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Arvaa puuttuva metadata tiedostopolun perusteella" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Älä lataa metatietoja kun kappaletta soitetaan" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Tutki tuntemattomien tiedostopäätteiden omaavien tiedostojen sisältö" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Sekalaiset" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Askel eteen-/taaksepäin:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "sekuntia" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Säädä äänenvoimakkuutta:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "prosentteina" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "NIMI" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "NIMI - ESITTÄJÄ" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "NIMI - ESITTÄJÄ - ALBUMI" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ESITTÄJÄ - NIMI" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ESITTÄJÄ - ALBUMI - NIMI" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ESITTÄJÄ - ALBUMI - KAPPALENUMERO. NIMI" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTISTI [ ALBUMI ] - KAPPALENUMERO. NIMI" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUMI - NIMI" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Luokka" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Mukautettu" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Nimikkeen muoto:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Muu merkkijono:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Ota suoratoiston tallennus käyttöön %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Liitännäistä äänen nauhoittamista varten ei ole saatavilla" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audaciouksen asetukset" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Peru" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Tallenna" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Lataa" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Lataa esiasetustiedosto" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Lataa EQF-tiedosto" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Tallenna esiasetustiedosto" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Tallenna EQF-tiedosto" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Jonomanageri" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Poista jonosta" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Työskennellään..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Virhe" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Tiedot" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Tallenna historiaan" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Avaa verkko-osoite" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Lisää verkko-osoite" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "T_yhjennä historia" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Anna verkko-osoite:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Avaa" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Seuraavat viestit ovat piilotettu.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Esiasetustiedostot (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Sulje" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Selaa" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Avaa kansio" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Lisää kansio" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Lisää" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Aseta fontti" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metatiedot" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Säveltäjä" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Esittäjä" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Nauhoitusvuosi" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Nauhoituspäivä" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Tekninen" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bittinopeus" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "MusicBrainz ID" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Palauta" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Virhe tunnisteita kirjoittaessa." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 tiedostoa valittu" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "_Tallenna %1 tiedostoa" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Taso" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Toiminto" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Viesti" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Lokin tarkastaja" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Vianetsintä" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Tiedot" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Varoitus" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "T_yhjennä" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Lokitaso:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Palvelut" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopioi" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..024090a --- /dev/null +++ b/po/fr.po @@ -0,0 +1,1512 @@ +# French translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# AO , 2012-2013 +# AO , 2019-2020 +# AO , 2017-2018 +# AO , 2016 +# AO , 2016 +# Oxayotl , 2013-2014 +# Oxayotl , 2011-2012 +# Oxayotl , 2011 +# Oxayotl , 2011,2013 +# AO , 2015 +# AO , 2013-2015 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-04-30 18:49+0000\n" +"Last-Translator: AO \n" +"Language-Team: French (http://www.transifex.com/audacious/audacious/language/fr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Afficher l’aide de la ligne de commande" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Afficher la version" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Commencer la lecture" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Mettre la lecture en pause" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Mettre en pause, sinon lire" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Arrêter la lecture" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Passer à la pièce précédente" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Passer à la pièce suivante" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Ajouter des fichiers à la liste de lecture" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Ajouter des fichiers à une liste de lecture temporaire" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Afficher la fenêtre principale" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Afficher la fenêtre « Sauter vers une plage »" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Démarrer sans interface graphique" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Quitter à l’arrêt de la lecture" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Imprimer les messages de débogage (peut être utilisé deux fois)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Exécuter en mode GTK" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Option inconnue : %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Option inconnue : -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Utilisation : audacious [OPTION] … [FICHIER]…\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Choisir l’instance à exécuter/contrôler" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d fichier trouvé" +msgstr[1] "%d fichiers trouvés" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Erreur en lisant %s :\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Aucun fichier n’a été trouvé." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nouvelle liste de lecture" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Entrée standard" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "CD audio, plage %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(erreur d’encodage de caractère)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "L’enregistrement des flux doit être configuré dans les paramètres du son avant de pouvoir être utilisé." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Erreur d’ouverture du flux de sortie" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Erreur d’enregistrement du flux de sortie" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Erreur en lisant %s :\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Le format son est invalide" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Lecture en cours" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Erreur d’ouverture %s :\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Erreur de chargement de %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Impossible de charger %s : l’extension du nom de fichier n’est pas prise en charge." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Erreur d’enregistrement de %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Impossible d’enregistrer %s : l’extension du nom de fichier n’est pas prise en charge." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Erreur de chargement du greffon" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Erreur de positionnement" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Format de fichier non reconnu" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Erreur de lecture des métadonnées" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stéréo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d canal" +msgstr[1] "%d canaux" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "CD Audio" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Plage %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(titre inconnu)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Modèle d’URI inconnu" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Nom de fichier invalide" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Mode d’accès invalide" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Crédits" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licence" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "À propos d’Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Annuler" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "Ne plus _demander" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Souhaitez-vous supprimer « %s » définitivement ?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Supprimer" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Supprimer la liste de lecture" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Comment souhaitez-vous nommer cette liste de lecture ?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Renommer" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Renommer la liste de lecture" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Veuillez choisir un préréglage pour exporter." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Fichier de préréglage…" + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Fichier EQF…" + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importer" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exporter" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Préréglages de l’égaliseur" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Enregistrer le préréglage" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Supprimer le préréglage sélectionné" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Annuler les changements" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "Activ_er" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Égaliseur" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Préréglages…" + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Remettre à zéro" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Préampli" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Ouvrir des fichiers" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Ouvrir" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Fermer la _fenêtre de dialogue à l’ouverture" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Ajouter des fichiers" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Ajouter" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Fermer la fenêtre de _dialogue lors de l’ajout" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Fermer" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Titre" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artiste" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Genre" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Année" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Plage" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Durée" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Format :" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Qualité :" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Débit binaire :" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambiant" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Musique de chambre" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Classique" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death métal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Facile à écouter" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy métal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-Hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Métal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "Nouvel âge" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Bruit" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-Hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Enregistrement réussi" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Erreur d’enregistrement" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Infos sur la pièce" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Artiste de l’album" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Commentaire" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Numéro de plage" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "Remplir _automatiquement les champs vides" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Enregistrer" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Précédent" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "Suiva_nt" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/D" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "Sa_uter" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Sauter à la positon (temps)" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Saisir une position (minutes:secondes) :" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Ajouter à la file" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "_Retirer de la file" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Sauter vers une plage" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtre :" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtre :" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Fermer après _le saut" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "Rem_placer" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Confirmer le remplacement" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Remplacer %s ?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Veuillez saisir une extension de nom de fichier ou choisir un format dans la liste déroulante." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Choisir un format par extension" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Exporter la liste de lecture" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exporter" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importer la plage de lecture" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importer" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Greffons…" + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "À propos de %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s — Paramètres" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Définir" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Paramètres" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "À propo_s" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Choisir un fichier" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Choisir un dossier" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Apparence" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Son" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Réseau" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Liste de lecture" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Greffons" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Avancés" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Général" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Effets" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualisation" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Entrée" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transport" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Artiste de l’album" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Numéro de plage" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nom de fichier" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Chemin du fichier" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Date" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Description" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Codec" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Qualité" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Aucune" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arabe" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Balte" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Chinois" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Grec" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hébreu" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japonais" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Coréen" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polonais" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Russe" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taïwanais" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turc" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "automatique" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "virgule flottante" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Tel que décodé" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Après avoir appliqué ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Après avoir appliqué les effets" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Après avoir appliqué la correction" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "D’après la lecture aléatoire" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interface :" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Greffon de sortie :" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Amplifier tous les fichiers :" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Amplifier les fichiers sans balise :" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Paramètres de sortie" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Profondeur du flux :" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Taille du tampon :" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Écrêtage logiciel" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Utiliser le contrôle logiciel du volume (non recommandé)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Paramètres d’enregistrement" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Flux d’enregistrement :" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Activer « ReplayGain »" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Mode :" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Éviter l’écrêtage (recommandé)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Nom d’hôte du mandataire :" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Port du mandataire :" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Nom d’utilisateur du mandataire :" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Mot de passe du mandataire :" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Paramètres réseau" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Configuration du mandataire" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Activer l’utilisation du mandataire" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Utiliser l’authentification avec le mandataire" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Utiliser un mandataire SOCKS" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Détecteur automatique d’encodage des caractères pour :" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Codage de caractères de repli :" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Comportement" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Reprendre la lecture au démarrage" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Mettre en pause au lieu de reprendre immédiatement" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Avancer si la pièce en cours est supprimée" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Vider la liste de lecture lors de l’ouverture de fichiers" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Ouvrir les fichiers dans une liste de lecture provisoire" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Affichage de la pièce" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Afficher les numéros des pièces" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Afficher un zéro au début (02:00 au lieu de 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Afficher les heures séparément (1:30:00 au lieu de 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exportation" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Utiliser des chemins relatifs si possible" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Illustration de l’album" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Chercher des images qui correspondent à ces mots (séparés par des virgules) :" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Exclure les images contenant ces mots (séparés par des virgules) :" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Chercher des images qui correspondent au nom de fichier de la pièce" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Recherche récursive" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Profondeur de la recherche :" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Fenêtre d’information contextuelle" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Afficher les fenêtres d’information contextuelles" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Délai de la fenêtre contextuelle (en dixièmes de seconde) :" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Afficher l’échelle de temps pour la pièce actuelle" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Compatibilité" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpréter \\ (barre oblique inverse) en tant que délimiteur de dossier" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Liste de lecture" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Ajouter des dossiers, récursivement" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Ajouter les dossiers imbriqués dans les fichiers de liste de lecture" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Métadonnées" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Deviner les métadonnées manquantes à partir du chemin du fichier" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Ne charger les métadonnées des pièces qu’à la lecture" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Sonder le contenu des fichiers sans extension de nom de fichier reconnue" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Divers" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Avancer/reculer en :" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "secondes" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Régler le volume de :" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "pour cent" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TITRE" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TITRE — ARTISTE" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TITRE — ARTISTE — ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTISTE — TITRE" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTISTE — ALBUM — TITRE" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTISTE — ALBUM — PLAGE. TITRE" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTISTE [ ALBUM ] — PLAGE. TITRE" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM — TITRE" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Catégorie" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Personnalisé" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Format du titre :" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Chaîne personnalisée :" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Activer l’enregistrement des flux audio avec le %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Aucun greffon d’enregistrement de son n’est proposé" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Paramètres d’Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Annuler" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Enregistrer" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Charger" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Charger un fichier de préréglage" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Charger un fichier EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Enregistrer le fichier de préréglage" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Enregistrer le fichier EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Gestionnaire de la file d’attente" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "Retirer de la _file d’attente" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Traitement en cours…" + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Erreur" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Informations" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "Enregistrer dans l’hi_storique" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Ouvrir une URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Ajouter une URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "Vider _l’historique" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Saisir une URL :" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Ouvrir" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Les messages à venir ont été cachés.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Fichiers de préréglages (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Fermer" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Parcourir" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Ouvrir un dossier" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Ajouter un dossier" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Ajouter" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Définir une police" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Métadonnées" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Compositeur" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Interprète" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Année d’enregistrement" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Date d’enregistrement" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Infos techniques" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Débit binaire" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "ID MusicBrainz" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Rétablir" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Erreur d’écrire des balises" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 fichiers ont été sélectionnés" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "_Enregistrer %1 fichiers" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Niveau" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Fonction" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Message" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Inspecteur de journaux" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Débogage" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Infos" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Avertissement" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Effac_er" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Niveau de journalisation :" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Services" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Copier" diff --git a/po/gl.po b/po/gl.po new file mode 100644 index 0000000..0cfccda --- /dev/null +++ b/po/gl.po @@ -0,0 +1,1506 @@ +# Galician translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# antiparvos, 2013-2018 +# antiparvos, 2013 +# Miguel Anxo Bouzada , 2013 +# Miguel Anxo Bouzada , 2012 +# Miguel Anxo Bouzada , 2012-2015 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-27 04:33+0000\n" +"Last-Translator: antiparvos\n" +"Language-Team: Galician (http://www.transifex.com/audacious/audacious/language/gl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: gl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Amosar a axuda da liña de ordes" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Amosa a versión" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Iniciar a reprodución" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Deter a reprodución" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pausar se reproduce, reproducir en caso contrario" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Parar a reprodución" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Ir á canción anterior" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Ir á seguinte canción" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Engadir ficheiros á lista de reprodución" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Engadir os ficheiros a unha lista temporal de reprodución" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Amosar a xanela principal." + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Amosar a xanela de salto á canción" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Iniciar sen interface gráfica" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Saír ao parar a reprodución" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Amosar mensaxes de depuración (pode usarse dúas veces)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Opción descoñecida: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Opción descoñecida: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Uso: audacious [OPCIÓN] ... [FICHEIRO] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Seleccionar instancia a executar/controlar" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d ficheiro atopado" +msgstr[1] "%d ficheiros atopados" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Produciuse un erro lendo %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Non se atoparon ficheiros." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nova lista de reprodución" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Entrada estándar" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "CD de son. pista %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(erro na codificación de caracteres)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "A gravación do fluxo debe estar configurada nos Axustes do son antes de usala." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Produciuse un erro abrindo o fluxo de saída" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Produciuse un erro gravando o fluxo de saída" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Produciuse un erro reproducindo %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Formato de son incorrecto" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Estase a reproducir" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Erro abrindo %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Erro cargando %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Non é posíbel cargar %s: extensión de nome de ficheiro non admitida." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Non é posíbel gardar %s: extensión de nome de ficheiro non admitida." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Produciuse un erro cargando o engadido" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Erro de busca" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Non se recoñeceu o formato do ficheiro" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Produciuse un erro lendo os metadatos" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Estéreo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d canle" +msgstr[1] "%d canles" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "CD de son" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Pista %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(título descoñecido)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "O esquema do URI é descoñecido" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Nome de ficheiro incorrecto" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Modo de acceso incorrecto" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Créditos" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licenza" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Sobre Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Cancelar" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "Non preguntar _de novo" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Confirma que quere retirar permanentemente «%s»?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Retirar" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Retirar a lista de reprodución" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Como desexa chamarlle a esta lista?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Renomear" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Renomear a lista de reprodución" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Ficheiro de predeterminacións..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Ficheiro EQF..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importar" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Predeterminacións do ecualizador" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Gardar predeterminacións" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Eliminar selección" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Reverter cambios" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Activar" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Ecualizador" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Predeterminacións..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Restabelecer a cero" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamplificador" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Abrir ficheiros" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Abrir" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Pechar o _diálogo ao abrir" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Engadir ficheiros" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Engadir" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Pechar o _diálogo ao engadir" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Pechar" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Título" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Interprete" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Álbum" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Xénero" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Ano" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Pista" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Duración" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formato:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Calidade:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Taxa de bits:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambiental" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Música de cámara" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Clásica" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Escoita doada" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folc" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Rock duro" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-Hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Ruído" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock & Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm & Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-Hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Gardouse correctamente" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Produciuse un erro ao gardar" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Información da canción" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Álbum Artista" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Comentario" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Número de pista" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Gardar" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "Se_guinte" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/D" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Ir a" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Saltar no tempo" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Introducir o tempo (minutos:segundos):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Cola" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Retirar da _cola" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Saltar á canción" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtro: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtro:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "_Pechar ao saltar" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Sobrescribir" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Confirmar sobrescritura" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Sobrescribir %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Escriba unha extensión do nome do ficheiro ou seleccione un formato da lista despregábel." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Seleccionar formato por extensión" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Exportar lista de reprodución" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exportar" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importar lista de reprodución" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importar" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Engadidos ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Sobre%s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Axustes de %s" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Estabelecer" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Axustes" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Sobre" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Escolla un ficheiro" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Escolla un cartafol" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Aparencia" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Son" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Rede" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Lista de reprodución" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Engadidos" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Avanzada" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Xeral" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efecto" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualización" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Entrada" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transporte" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Interprete do álbum" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Número de pista" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nome de ficheiro" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Ruta ao ficheiro" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Data" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Descrición" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Códec" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Calidade" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Ningún" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Árabe" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Báltico" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Chinés" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Grego" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebreo" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Xaponés" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Coreano" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polaco" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Ruso" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanés" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turco" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automático" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Coma flotante" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Como descodificado" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Despois de aplicar a normalización do volume" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Despois de aplicar os efectos" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Despois de aplicar a ecualización" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Baseado no modo aleatorio" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interface:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Engadido de saída:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Amplificar todos os ficheiros:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Amplificar os ficheiros sen etiqueta:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Configuración da saída" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Profundidade de bit:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Tamaño do búfer:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Recorte suave de picos" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Utilizar o software de control de volume (non recomendado)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Axustes da gravación" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Gravar fluxo:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Activar ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Modo:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Evitar a saturación (recomendado)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Nome do servidor proxy:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Porto do proxy:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Nome de usuario no proxy:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Contrasinal no proxy:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Axustes de rede" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Configuración do proxy" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Activar o uso de proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Usar autenticación co proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Detector de codificación de caracteres automático para: " + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Codificación de caracteres alternativa:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Comportamento" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Continuar a reprodución ao iniciar" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Deter no canto de continuar inmediatamente" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Avanzar cando se elimina a canción actual" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Limpar a lista de reprodución cando se abran novos ficheiros" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Abrir os ficheiros nunha lista temporal de reprodución" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Visor de cancións" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Amosar os números das cancións" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Amosar ceros á esquerda (02:00 no canto de 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Mostrar horas por separado (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Usar rutas relativas cando sexa posíbel" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Portada" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Buscar imaxes que correspondan con estas palabras (separadas por comas):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Excluir imaxes que correspondan con estas palabras (separadas por comas):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Buscar imaxes que correspondan co nome de ficheiro da canción" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Buscar recursivamente" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Profundidade da busca" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Mensaxe emerxente de información" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Amosar a mensaxe emerxente de información" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Atraso da mensaxe emerxente (décimas de segundo):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Amosar a escala de tempo da canción actual" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Compatibilidade" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpretar o caracter «\\» (barra invertida) como indicador dun nivel na árbore de ficheiros" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Lista de reprodución" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Engadir cartafoles recursivamente" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Engadir cartafoles aniñados aos ficheiros da lista de reprodución" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadatos" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Supoñer os metadatos que faltan da ruta do ficheiro" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Non cargar a información de metadatos ata reproducir" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Investigar o contido dos ficheiros sen unha extensión recoñecíbel no nome do ficheiro." + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Varios" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "segundos" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TÍTULO" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TÍTULO - ARTISTA" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TÍTULO - ARTISTA - ÁLBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTISTA - TÍTULO" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTISTA - ÁLBUM - TÍTULO" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTISTA - ÁLBUM - PISTA. TÍTULO" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTISTA [ ÁLBUM ] - PISTA. TÍTULO" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ÁLBUM - TÍTULO" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Categoría:" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Personalizada" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Formato do título:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Cadea personalizada" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Activar a gravación do fluxo de son con %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Non hai dispoñíbel ningún engadido para gravar son " + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Axustes do Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Cancelar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Gardar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Cargar" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Cargar o ficheiro de predeterminados" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Cargar o ficheiro EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Gardar o ficheico de predeterminados" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Gardar o ficheiro EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Xestor da cola" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Retirar da cola" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Traballando..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Erro" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Información" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "Gardar no hi_storial" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Abrir un URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Engadir un URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "_Limpar historial" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Introduza o URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Abrir" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(O resto de mensaxes foron agochados.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Pechar" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Examinar" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Abrir cartafol" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Engadir un cartafol" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Engadir" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadatos" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Compositor" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Intérprete" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Ano da gravación" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Data da gravación" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Técnico" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Taxa de bits" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Nivel" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Función" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Mensaxe" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Inspector do rexistro" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Depurar" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Información" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Aviso" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "L_impar" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Nivel do rexistro:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Servizos" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Copiar" diff --git a/po/hu.po b/po/hu.po new file mode 100644 index 0000000..b1d7a6c --- /dev/null +++ b/po/hu.po @@ -0,0 +1,1513 @@ +# Hungarian translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Agócs Dániel , 2015 +# Balázs Glatz , 2015 +# Balázs Meskó , 2018 +# Báthory Péter , 2015 +# Ferenc Szabo , 2013 +# fyghter04 , 2014 +# fyghter04 , 2014 +# Gábor Sávolyi, 2016 +# Laszlo Dvornik , 2006 +# Péter Polonkai , 2010 +# Péter Polonkai , 2010-2012,2014-2016 +# Ferenc Szabo , 2013 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Péter Polonkai \n" +"Language-Team: Hungarian (http://www.transifex.com/audacious/audacious/language/hu/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: hu\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Parancssori súgó megjelenítése" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Verzió mutatása" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Lejátszás indítása" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Lejátszás szüneteltetése" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Lejátszás esetén szüneteltetés, különben lejátszás" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Lejátszás megállítása" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Ugrás az előző számhoz" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Ugrás a következő számhoz" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Fájlok hozzáadása a lejátszó listához" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Fájlok hozzáadása egy ideiglenes lejátszólistához" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Főablak megjelenítése" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Jelenítse meg az \"ugrás a dalra\" ablakot" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Indítás grafikus felület nélkül" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Kilépés a lejátszás megállásakor" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Hibakeresési üzenetek kiírása (kétszer is használható)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Ismeretlen kapcsoló: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Ismeretlen kapcsoló: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Használat: audacious [KAPCSOLÓ] … [FÁJL] …\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Válassza ki a futtatandó/vezérelendő példányt" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d fájl található" +msgstr[1] "%d fájl található" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Hiba a(z) %s olvasásakor\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Fájl nem található." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Új lejátszólista" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Szabványos bemenet" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Audio CD, %s. szám" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(karakterkódolási hiba)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "A hangfolyam felvételét be kell állítani a Hangbeállításokban, mielőtt az használható lenne." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Hiba a kimeneti folyam megnyitásakor" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Hiba a kimeneti folyam rögzítésekor" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Hiba a(z) %s lejátszásakor:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Érvénytelen hangformátum" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Most játszott" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Hiba a(z) %s megnyitáskor:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Hiba a(z) %s betöltésekor." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "A(z) %s nem tölthető be: a fájlkiterjesztés nem támogatott." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "A(z) %s nem menthető: a fájlkiterjesztés nem támogatott." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Hiba a bővítmény betöltésekor" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Tekerési hiba" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "A fájl formátuma nem ismert" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Hiba a metaadatok olvasásakor" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Sztereó" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d csatorna" +msgstr[1] "%d csatorna" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Audio CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "%d. szám" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(ismeretlen cím)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Ismeretlen URI séma" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Érvénytelen fájlnév" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Érvénytelen hozzáférési mód" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Köszönet" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licenc" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Az Audacious névjegye" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Mégse" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Ne kérdezze többször" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Biztos, hogy véglegesen törli ezt: \"%s\"?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Eltávolítás" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Lejátszólista törlése" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Mi legyen a lejátszólista neve?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "Át_nevezés" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Lejátszólista átnevezése" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Előbeállítás fájl …" + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF fájl …" + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importálás" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exportálás" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Hangszínszabályzó előbeállítások" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Előbeállítás mentése" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Kiválasztott törlése" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Változtatások visszavonása" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Engedélyezés" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Hangszínszabályzó" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Előbeállítások …" + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Nullázás" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Előerősítés" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Fájlok megnyitása" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Megnyitás" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "_Párbeszédablak bezárása megnyitás után" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Fájlok hozzáadása" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Hozzáadás" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "_Párbeszédablak bezárása hozzáadás után" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Bezárás" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Cím" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Előadó" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Műfaj" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Év" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Szám" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Hossz" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formátum:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Minőség:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bitráta:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Kamarazene" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klasszikus" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Diszkó" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gengszter rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Kemény rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "Új hullám" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Szving" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Sikeres mentés" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Mentési hiba" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Dal információk" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Album előadó" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Megjegyzés" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Sorszám" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Mentés" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Következő" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "–" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Ugrás" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Ugrás időpontra" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Idő megadása (perc:másodperc):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Sorba állítás" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "_Kiszedés a sorból" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Ugrás számra" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Szűrő: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "Szű_rő: " + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Bezárás _ugrás után" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Felülírás" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Felülírás megerősítése" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Felülírja ezt: %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Írjon be egy kiterjesztést, vagy válasszon egy formátumot a legördülő listából." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Formátum kiválasztása kiterjesztés alapján" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Lejátszólista exportálása" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exportálás" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Lejátszólista importálása" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importálás" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Bővítmények …" + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "A(z) %s névjegye" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s beállítások" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Beállítás" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Beállítások" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Névjegy" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Fájl választása" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Mappa választása" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Megjelenés" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Hang" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Hálózat" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Lejátszólista" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Bővítmények" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Speciális" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Általános" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Effekt" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Megjelenítés" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Bemenet" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Átvitel" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Album előadó" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Szám sorszáma" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Fájlnév" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Fájl elérési útja" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Dátum" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Kodek" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Minőség" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Nincs" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arab" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Balti" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Kínai" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Görög" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Héber" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japán" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Koreai" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Lengyel" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Orosz" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Tajvani" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Török" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automatikus" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Lebegőpontos" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Dekódolt" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "A lejátszási erősítés alkalmazása után" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Az effektek alkalmazása után" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "A hangszínszabályozás alkalmazása után" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Véletlenszerű sorrend alapján" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Felület:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Kimeneti bővítmény:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Összes fájl erősítése:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Címkézetlen fájlok erősítése:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Kimeneti beállítások" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bitmélység:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Pufferméret:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Szoftveres vágás" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Szoftveres hangerőszabályzás használata (nem ajánlott)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Felvételi beállítások" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Folyam rögzítése:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "Lejátszási erősítés" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Lejátszási erősítés engedélyezése" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Mód:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Vágás megakadályozása (ajánlott)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Proxy gépnév:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Proxy port:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Proxy felhasználónév:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Proxy jelszó:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Hálózati beállítások" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Proxy beállítása" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Proxyhasználat engedélyezése" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Hitelesítés használata a proxyval" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automatikus karakterkódolás felismerése ennél:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Tartalék karakterkódolások:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Viselkedés" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Lejátszás folytatása indításkor" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Szünet helyett azonnali folytatás" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Továbblépés, ha a jelenlegi zeneszám törlésre kerül" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Lejátszólista törlése fájlok megnyitásakor" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Fájlok megnyitása egy ideiglenes lejátszólistában" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Szám megjelenítése" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "A dalok számának megjelenítése" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Vezető nullák megjelenítése (2:00 helyett 02:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Óraelválasztó megjelenítése (1:300:00 vagy 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exportálás" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Használjon relatív útvonalakat, amikor csak lehetséges" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Albumborító" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Ezen szavaknak megfelelő képek keresése (vesszővel elválasztva):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Ezen szavaknak megfelelő képek kizárása (vesszővel elválasztva):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "A dal fájlnevével megegyező képek keresése" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Keresés rekurzívan" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Keresési mélység:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Felbukkanó információk" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Felbukkanó információs ablak megjelenítése" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Felbukkanó ablak késleltetése (tizedmásodperc):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Aktuális dal idősávjának megjelenítése" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Kompatibilitás" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "\\ (visszaper jel) mappahatárolóként értelmezése" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Lejátszólista" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Mappák hozzáadása rekurzívan" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "A lejátszólista fájlokba ágyazott mappák hozzáadása" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metaadat" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "A hiányzó metaadatok kitalálása az elérési útból" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "A dal lejátszásáig ne töltse be a metaadatokat" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "A fájlok tartalmának vizsgálata, ha nem ismert a fájl kiterjesztése" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Egyéb" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "másodperc" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "CÍM" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "CÍM - ELŐADÓ" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "CÍM - ELŐADÓ - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ELŐADÓ - CÍM" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ELŐADÓ - ALBUM - CÍM" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ELŐADÓ - ALBUM - SZÁM. CÍM" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ELŐADÓ [ ALBUM ] - SZÁM. CÍM" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - CÍM" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategória" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Egyéni" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Címformátum:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Egyéni karakterlánc:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Hangfolyam felvételének engedélyezése ezzel: %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Nincs elérhető hangrögzítő bővítmény" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious beállítások" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Mégse" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Mentés" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Betöltés" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Előbeállítás fájl betöltése" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "EQF fájl betöltése" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Előbeállítás fájl mentése" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "EQF fájl mentése" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Várakozási sor kezelő" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Kiszedés a sorból" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Folyamatban …" + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Hiba" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Információk" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Mentés az előzmények közé" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "URL megnyitása" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "URL hozzáadása" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "_Előzmények törlése" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "URL megadása:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Megnyitás" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(További üzenetek el vannak rejtve.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Bezár" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Böngészés" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Mappa megnyitása" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Mappa hozzáadása" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Hozzáadás" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metaadatok" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Zeneszerző" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Előadó" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Rögzítés éve" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Rögzítés dátuma" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Műszaki" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bitráta" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Szint" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Funkció" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Üzenet" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Napló vizsgáló" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Hibakeresés" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Információ" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Figyelmeztetés" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "_Törlés" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Naplózási szint:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Szolgáltatások" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Másolás" diff --git a/po/id_ID.po b/po/id_ID.po new file mode 100644 index 0000000..7bebb27 --- /dev/null +++ b/po/id_ID.po @@ -0,0 +1,1524 @@ +# Indonesian translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Rahman Yusri Aftian , 2012,2014 +# Rahman Yusri Aftian , 2012 +# Andika Triwidada , 2012 +# Andika Triwidada , 2012 +# Ardjuna , 2013-2015 +# Arif Syamsudin , 2012 +# Bervianto Leo Pratama , 2016 +# , 2012,2014 +# Arif Syamsudin , 2012 +# Hasan Al Banna, 2012 +# , 2012 +# ivanzulfikar , 2014 +# ivanzulfikar , 2014 +# Liffindra Angga Zaaldian , 2015 +# Mohamad Hasan Al Banna, 2012 +# se7entime , 2012 +# Muhammad Mauli Mubassari , 2019 +# Rahman Aftian <>, 2012 +# Rahman Yusri Aftian , 2012,2014 +# , 2012 +# , 2012 +# se7entime , 2012 +# Adrianus Yoza Aprilio , 2012 +# Adrianus Yoza Aprilio , 2012 +# Adrianus Yoza Aprilio , 2012 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Rahman Yusri Aftian \n" +"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/audacious/audacious/language/id_ID/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: id_ID\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Tampilkan bantuan untuk baris-perintah" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Tampilkan versi" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Mulai pemutaran lagu" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Jeda pemutaran lagu" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Jeda pemutaran jika sedang memutar, putar jika tidak sedang memutar" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Hentikan pemutaran lagu" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Lompat ke lagu sebelumnya" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Lompat ke lagu berikutnya" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Tambah berkas ke dalam daftar lagu" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Tambah berkas ke daftar putar sementara" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Tampilkan jendela utama" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Tampilkan jendela \"Loncat ke Lagu\"" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Mulai tanpa tampilan antarmuka secara grafis" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Keluar ketika berhenti memutar lagu" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Cetak pesan debug (dapat digunakan dua kali)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Pilihan tidak dikenal: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Pilihan tidak dikenal: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Penggunaan: audacious [PILIHAN] ... [BERKAS] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d berkas ditemukan" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Gagal membaca %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Tidak ada file yang ditemukan." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Daftar putar baru" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Masukan standar" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "CD Audio, trek %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(galat pada penyandian karakter)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Gagal memainkan %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Format audio tidak sah" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Sedang Diputar" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Gagal membuka %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Gagal memuat %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Tidak dapat memuat %s: ekstensi nama berkas tidak didukung." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Tidak dapat menyimpan %s: ekstensi nama berkas tidak didukung." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Gagal memuat pengaya" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Galat pada pencarian" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Format berkas tidak dikenal" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Galat saat membaca metadata" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanal" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "CD Audio" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Trek %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(judul tidak diketahui)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Skema URI tidak diketahui" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Nama berkas tidak sah" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Mode akses tidak valid" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Kredit" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Lisensi" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Tentang Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Batal" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Jangan tanya lagi" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Apakah kamu mau menghapus dengan permanen “%s”?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Hapus" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Hapus Daftar Putar" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Apakah anda suka dan memanggil daftar putar ini?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "Gant_i Nama" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Ganti Nama Daftar Lagu" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Berkas Preset ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Berkas EQF ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Impor" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Ekspor" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Setelan Ekuilizer" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Simpan Setelan" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Hapus Item Terpilih" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Kembalikan Perubahan" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Gunakan" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Ekualiser" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Preset ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Setel ke Nol" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamp" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Buka Berkas" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "B_uka" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Tutup _dialog buka" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Tambah Berkas" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Tambah" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Tutup _dialog buka" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Keluar" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Judul" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artis" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Aliran" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Tahun" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Trek" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Panjang" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Format:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Kualitas:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bitrate:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Chamber Music" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klasik" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disko" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Mudah Didengarkan" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Bising" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock & Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm & Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Penyimpanan berhasil" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Penyimpanan galat" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Info Lagu" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Album Artis" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Komentar" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Nomor Trek" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Simpan" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "Sela_njutnya" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d Kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/A" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Lompat" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Loncat ke Waktu" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Masukkan waktu (menit:detik):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "Masuk _Antrian" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Keluar Antria_n" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Loncat ke Lagu" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filter: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filter:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Ke_luar loncat" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Timpa" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Konformasi Penimpaan" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Menimpa %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Mohon ketikkan nama ekstensi berkas atau pilih format yang sesuai dari daftar." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Pilih Format Ekstensi" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Ekspor Daftar Main" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Ekspor" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Impor Daftar Main" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Impor" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Plugins ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Tentang %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Pengaturan" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Set" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Settings" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "Tent_ang" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Pilih Berkas" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Pilih Direktori" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Penampilan" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Suara" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Jaringan" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Daftar putar" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Pengaya" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Lanjutan" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Umum" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efek" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualisasi" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Masukan" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transpor" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Nomor trek" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nama berkas" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Lokasi berkas" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Tanggal" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Kodek" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Kualitas" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Kosong" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arab" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltic" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Cina" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Yunani" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Ibrani" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Jepang" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Korea" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polandia" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Rusia" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwan" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turki" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Otomatis" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Titik mengambang" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Setelah menerapkan ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Setelah menerapkan efek" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Pengaya keluaran:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Kuatkan semua berkas:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Kuatkan berkas yang tak ditandai:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Setelan Keluaran" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Kedalaman bit:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Ukuran penyangga:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Kliping lunak" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Gunakan pengatur volume (tidak direkomendasikan)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Pengaturan Perekaman" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Aktifkan ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Cegah pemangkasan (direkomendasikan)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Nama host proksi:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Porta proxy:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Nama pengguna proxy:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Sandi proxy:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Pengaturan Jaringan" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "KOnfigurasi Proxy" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Gunakan proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Gunakan otentikasi pada proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Deteksi enkoder karakter otomatis untuk:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Enkoder karakter standar:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Perilaku" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Lanjut putar saat aplikasi dimulai" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Jeda pemutaran daripada langsung lanjutkan segera" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Jika lagu terkini terhapus, lanjut putar lagu lain" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Bersihkan daftar lagu ketika membuka berkas" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Buka berkas pada daftar lagu sementara" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Tampilan Lagu" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Tampilkan no. urut daftar lagu" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Gambar Sampul" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Cari gambar yang sesuai dengan kata tersebut (pisahkan dengan tanda koma):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Mengecualikan gambar yang sesuai dengan kata tersebut (pisahkan dengan tanda koma):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Cari gambar yang sesuai dengan nama berkas" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Cari secara rekursif" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Kedalaman pencarian:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Informasi Jendela Popup" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Munculkan halaman informasi popup" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Tunda popup (persepuluh detik):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Tampilkan skala waktu untuk lagu saat ini" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Kecocokan" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Tafsirkan \\ (garis miring terbalik) sebagai pembatas folder" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadata" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Prediksi metadata yang hilang dari lokasi berkas" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Jangan muat metadata hingga lagu diputar" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Jajaki juga isi berkas yang tidak dikenal ekstensinya" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Miscellaneous" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "detik" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "JUDUL" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "JUDUL - ARTIS" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "JUDUL - ARTIS - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTIS - JUDUL" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTIS - ALBUM - JUDUL" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTIS - ALBUM - TREK. JUDUL" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTIS [ ALBUM ] - TREK. JUDUL" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - JUDUL" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategori" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Pilihan" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Format judul:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Rangkaian kata gubahan:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Tidak ada plug-in perekam audio yang tersedia" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Seting Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Batal" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Simpan" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Muat" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Muat Berkas Preset" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Muat Berkas EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Simpan Berkas Preset" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Simpan Berkas EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Manajer Antrian" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Hapus dari antrian" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Sedang bekerja ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Galat" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Informasi" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Buka URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Tambah URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Masukkan URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Buka" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Pesan lebih lanjut telah disembunyikan.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Telusuri" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Buka Folder" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Tambah Folder" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Tambah" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadata" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Komposer" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Penyanyi" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Tahun Rekaman" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Tanggal Rekaman" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Teknis" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bitrate" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Tingkat" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Fungsi" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Pesan" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Pemantau Log" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Debug" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Keterangan" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Peringatan" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Tingkat Log:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Layanan" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Salin" diff --git a/po/it.po b/po/it.po new file mode 100644 index 0000000..b50336e --- /dev/null +++ b/po/it.po @@ -0,0 +1,1516 @@ +# Italian translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Alessio D'Ascanio , 2004 +# Diego 'Flameeyes' Pettenò , 2006 +# Diego 'Flameeyes' Pettenò , 2007 +# Federico , 2013 +# Federico , 2013 +# Gaetano Ingrasciotta , 2012 +# Gaetano Ingrasciotta , 2012 +# eagleman , 2020 +# Giosuè Sulipano , 2020 +# Giuseppe D. B. , 2012 +# Jacopo Lorenzetti , 2011, 2012 +# Jacopo Lorenzetti , 2011-2012 +# Nicola Manini , 2014 +# Nicola Manini , 2014-2015 +# Saverio , 2014 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-04-25 14:36+0000\n" +"Last-Translator: eagleman \n" +"Language-Team: Italian (http://www.transifex.com/audacious/audacious/language/it/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: it\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Mostra l'aiuto della linea di comando" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Mostra versione" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Inizia la riproduzione" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pausa la riproduzione" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Interrompi se in riproduzione, altrimenti riproduci" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Termina la riproduzione" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Salta al brano precedente" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Salta al brano successivo" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Aggiunge file alla playlist" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Aggiungi files alla playlist temporanea" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Visualizza la finestra principale" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Mostra la finestra di salto-a-brano" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Parti senza interfaccia grafica" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Esci quando la riproduzione è stoppata" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Stampa i messaggi di debug (può essere usato due volte)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Esegui in modalità GTK" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Opzione sconosciuta: %s\n\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Opzione sconosciuta: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Uso: audacious [OPZIONE] ... [FILE] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Seleziona l'istanza da eseguire/controllare" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Trovato %d file" +msgstr[1] "Trovati %d file" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Errore durante la lettura %s: %s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Nessun file trovato." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nuova playlist" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Standard input" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "CD Audio, traccia %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(errore codifica carattere)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "La registrazione del flusso deve essere configurata nelle Impostazion Audio prima di poter essere usata." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Errore in apertura del flusso in uscita" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Errore nella registrazione del flusso in uscita" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Errore nella riproduzione %s: %s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Formato audio non valido" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "In riproduzione" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Errore durante l'apertura di %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Errore nel caricamento di %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Impossibile caricare %s: estensione non supportata" + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Errore nel salvataggio di %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Impossibile salvare %s: estensione non supportata" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Errore nel caricamento del plugin" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Errore di ricerca" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Formato del file non riconosciuto" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Errore durante la lettura dei meta dati" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d canale" +msgstr[1] "%d canali" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "CD Audio" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Traccia %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(titolo sconosciuto)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Schema dell'URI sconosciuto" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Nome del file non valido" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Modo d'accesso non valido" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Crediti" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licenza" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Informazioni su Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Annulla" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Non chiedere più" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Vuoi cancellare permanentemente \"%s\"?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Cancella" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Cancella la playlist" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Che nome dai a quest playlist?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Rinomina" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Rinomina playlist" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Per favore, seleziona un preset da esportare." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "File di predefiniti ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "File EQF ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importa" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Esporta" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Preimpostazione dell'equalizzatore" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Salva i predefiniti" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Cancella quanto selezionato" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Torna indietro eliminando i cambiamenti" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Abilita" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Equalizzatore" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Predefiniti ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Resetta a zero" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamplificazione" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Apri file" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Apri" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Chiudi il _dialogo all'apertura" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Aggiungi file" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "Aggiungi" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Chiudi il _dialogo dopo l'aggiunta" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Chiudi" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Titolo" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artista" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Genere" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Anno" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Traccia" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Lunghezza" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formato:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Qualità:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bitrate:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Musica da camera" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Classica" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Salvataggio completato" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Errore di salvataggio" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Info Brano" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Album Artista" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Commento" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Numero di brano" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "_Compilazione automatica dei campi vuoti" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Salva" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Precedente" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Successivo" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/D" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "Salta" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Salta alla posizione" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Inserisci tempo (minuti:secondi):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Coda" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Rimuovi dalla _coda" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Vai al brano" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtro: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtra:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Chiudi saltando" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "Sovrascrivi" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Confermi di voler sovrascrivere" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Sovrascrivere %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Scrivi qui un'estensione oppure seleziona dalla lista" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Seleziona il formato a partire dall'estensione" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Esporta playlist" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "Esporta" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importa playlist" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "Importa" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Plugins ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Informazioni su %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Impostazioni di %s" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Imposta" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Impostazioni" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "Informazioni" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Seleziona file" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Scegli una cartella" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Aspetto" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Audio" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Rete" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Playlist" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Plugin" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Avanzate" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Generici" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Effetto" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualizzazione" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Ingresso" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Trasporto" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Artista" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Numero di traccia" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nome del file" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Percorso del file" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Data" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Descrizione" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Codec" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Qualità" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Nessuna" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Araba" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltica" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Cinese" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Greca" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Ebraica" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Giapponese" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Coreana" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polacca" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Russa" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanese" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turca" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automatica" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Virgola mobile" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Come decodificata" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Dopo l'applicazione di ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Dopo l'applicazione degli effetti" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Dopo l'applicazione dell'equalizzazione" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Basata sula casualità" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interfaccia:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Plugin di uscita:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Amplifica tutti i file:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Amplifica i file senza tag:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Impostazioni di uscita" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Profondità di bit:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Dimensione del buffer:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Clipping leggero" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Utilizza controllo volume software (non raccomandato)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Impostazioni di registrazione" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Registra flusso:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Abilita ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Modalità:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Evita il clipping (raccomandato)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Host del proxy:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Porta del proxy:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Utente proxy:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Password proxy:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Impostazioni di rete" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Configurazione proxy" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Abilita utilizzo del proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Usa autenticazione con il proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Usa proxy SOCKS" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Individuazione automatica della codifica dei caratteri per:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Codifiche di riserva dei caratteri:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Comportamento" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Riprendi la riproduzione all'avvio" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Metti in pausa invece di riprendere la riproduzione immediatamente" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Avanza quando il brano corrente viene eliminato" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Cancella la playlist quando si aprono i file" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Apri i file in una playlist temporanea" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Visualizzazione del brano" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Mostra numeri dei brani" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Visualizza zero iniziali (02:00 contro 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Visualizza ore saparatamentey (1:30:00 contro 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Esporta" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Usa i percorsi relativi quando possibile" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Cover Album" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Ricerca elementi contenenti le parole :" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Escludi elementi corrispondenti alle seguenti parole (separati da virgola):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Ricerca elementi corrispondenti al nome del brano" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Cerca ricorsivamente" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Ricerca avanzata:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Informazioni popup" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Mostra Finestra informazioni" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Ritardo popup (decimi di secondo):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Mostra scala di tempo per il brano corrente" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Compatibilità" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpreta\\ (backslash) come un delimitatore di cartella" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Playlist" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Aggiungi cartelle ricorsivamente" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Aggiungi cartelle annidate nei file delle playlist" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadati" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Indovina i metadati mancanti dal percorso del file" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Non caricare i metadati dei brani finché non vengono riprodotti" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Sonda il contenuto dei file con estensione non riconsciuta" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Varie" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Vai avanti/indietro al:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "secondi" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Regola il volume al:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "percento" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TITOLO" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TITOLO - ARTISTA" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TITOLO - ARTISTA - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTISTA - TITOLO" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTISTA - ALBUM - TITOLO" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTISTA - ALBUM - TRACCIA. TITOLO" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTISTA [ALBUM] - TRACCIA. TITOLO" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - TITOLO" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Categoria" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Personalizzato" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Formato titolo:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Stringa personalizzata:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Abilta la registrazione di flusso audio con%s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Nessun plugin di registrazione audio disponibile" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Impostazioni di audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Annulla" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Salva" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Carica" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Carica file di predefiniti" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Carica file EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Salva file di predefiniti" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Salva file EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Gestione coda" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "Togli dalla coda" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Elaborazione ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Errore" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Informazioni" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Salva nella cronologia" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Apri URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Aggiungi URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "S_vuota cronologia" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Inserisci URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Apri" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Ulteriori messaggi sono stati nascosti.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "File Preset (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Chiudi" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Sfoglia" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Apri cartella" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Aggiungi cartella" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Aggiungi" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Imposta carattere" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Meta dati" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Compositore" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Esecutore" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Anno di registrazione" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Data di registrazione" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Tecnico" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bitrate" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "ID MusicBrainz" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Inverti" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Errore nella scrittura dei tag(s)" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 file selezionati" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "_Salva %1 file" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Livello" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Funzione" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Messaggio" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Ispettore di log" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Debug" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Informazioni" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Attenzione" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Sv_uota" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Livello di log" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Servizi" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Copia" diff --git a/po/ja.po b/po/ja.po new file mode 100644 index 0000000..9cb91f8 --- /dev/null +++ b/po/ja.po @@ -0,0 +1,1512 @@ +# Japanese translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# ABE Tsunehiko, 2013 +# ABE Tsunehiko, 2015-2018 +# natird zoto , 2012 +# ABE Tsunehiko, 2013 +# Nastuko Toda , 2012 +# Mika Kobayashi, 2014 +# Mika Kobayashi, 2014-2015 +# Nastuko Toda , 2012 +# natird zoto , 2012 +# natird zoto , 2012 +# Shuuji TAKAHASHI , 2012-2014 +# Shuuji TAKAHASHI , 2016 +# ABE Tsunehiko, 2013 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Shuuji TAKAHASHI \n" +"Language-Team: Japanese (http://www.transifex.com/audacious/audacious/language/ja/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ja\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "コマンドラインのヘルプを表示" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "バージョンを表示" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "再生" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "一時停止" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "再生していたら一時停止し、再生していなければ再生する" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "停止" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "前の曲にスキップ" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "次の曲にスキップ" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "プレイリストにファイルを追加" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "一時プレイリストにファイルを追加" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "メインウィンドウを表示する" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "ジャンプトゥソングウィンドウを表示する" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "グラフィカルインターフェイスなしで開始" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "再生完了時に終了する" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "デバッグ用メッセージを表示 (-VV のように2個続ける用法あり)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "不明なオプションです: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "不明なオプションです: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "使い方: audacious [オプション] ... [ファイル] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "コントロールするインスタンスを選択してください" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d 個のファイルが見つかりました" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "読み込みエラー %s\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "ファイルが見つかりません。" + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "新規プレイリスト" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "標準入力" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "オーディオ CD、トラック %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(文字のエンコーディングエラー)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "録音を始める前にあらかじめオーディオの設定を行う必要があります。" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "出力ストリームを開けません" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "出力ストリームを録音できませんq" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "%s の再生中に次のエラーが発生しました\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "無効なオーディオ形式" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "再生中" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "%s を開く際にエラー:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "%s の読込みエラー" + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "%s を読込めません: 対応していないファイル拡張子です。" + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "%s を保存することができません: 対応していないファイル拡張子です。" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "プラグインのロードエラー" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "シークエラー" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "ファイル形式を認識することができません" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "メタデータを読込む際にエラー" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "モノラル" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "ステレオ" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d チャンネル" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "オーディオ CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "トラック %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(不明なタイトル)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "不明な URI スキーマ" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "無効なファイル名" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "アクセスモードが無効です" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "クレジット" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "ライセンス" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Audacious について" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "キャンセル(_C)" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "再び表示しない(_D)" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "\"%s\" を完全に削除しますか?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "削除(_R)" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "プレイリストを削除" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "プレイリストの名前を入力して下さい。" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "名前を変更(_R)" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "プレイリストをリネーム" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "プリセットファイル ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF ファイル ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "インポート" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "エクスポート" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "イコライザーのプリセット" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "プリセットの保存" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "プリセットの削除" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "変更を元に戻す" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "有効(_E)" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "イコライザー" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "プリセット ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "ゼロにリセット" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "プリアンプ" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "ファイルを開く" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "開く(_O)" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "開いたらダイアログを閉じる(_D)" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "ファイルの追加" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "追加(_A)" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "追加したらダイアログを閉じる(_D)" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "閉じる(_C)" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "タイトル" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "アーティスト" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "アルバム名" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "ジャンル" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "制作年" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "トラック" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "長さ" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "形式:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "音質:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "ビットレート:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "アシッドジャズ" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "アシッドロック" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "アンビエント" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "ビバップ" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "ブルーグラス" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "ブルース" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "チェインバーミュージック" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "クラシカル" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "カントリー" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "デスメタル" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "ディスコ" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "イージーリスニング" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "フォーク" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "ファンク" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "ギャングスタラップ" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "ゴスペル" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "グランジ" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "ハードロック" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "ヘヴィメタル" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "ヒップホップ" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "ハウス" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "ジャズ" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "ジャングル" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "メタル" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "ニューエイジ" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "ニューウェーブ" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "ノイズ" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "ポップ" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "パンクロック" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "ラップ" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "レゲエ" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "ロック" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "ロックンロール" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "R&B" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "スカ" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "ソウル" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "スウィング" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "テクノ" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "トリップホップ" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "保存が完了しました" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "保存に失敗しました" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "曲の情報" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "アルバムアーティスト" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "コメント" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "トラック番号" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "保存(_S)" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "次の曲へ(_N)" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/A" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "ジャンプ(_J)" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "指定した時間へジャンプ" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "時間を入力してください (分:秒):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "キューに追加(_Q)" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "キューから外す(_U)" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "指定した曲にジャンプ" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "フィルター:" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "フィルター(_F):" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "ジャンプしたらダイアログを閉じる(_L)" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "上書き保存(_O)" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "上書きする" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "%s を上書きしてもよろしいですか?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "ファイルの拡張子を入力するか、ドロップダウンリストからフォーマットを選んでください" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "拡張子でフォーマットを選択" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "プレイリストを出力" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "エクスポート(_E)" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "プレイリストを読み込み" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "インポート(_I)" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "プラグイン(_P)" + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "%s について" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s の設定" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "設定(_S)" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "設定(_S)" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "情報(_A)" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "ファイルの選択" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "フォルダーの選択" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "外見" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "オーディオ" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "ネットワーク" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "プレイリスト" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "プラグイン" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "高度" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "一般" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "エフェクト" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "視覚化" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "インプット" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "トランスポート" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "アルバムアーティスト" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "トラック番号" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "ファイル名" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "ファイルパス" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "日付" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "コーデック" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "音質" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "なし" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "アラビア語" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "バルト諸語" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "簡体中国語" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "ギリシア語" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "ヘブライ語" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "日本語" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "韓国語" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "ポーランド語" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "ロシア語" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "繁体中国語" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "トルコ語" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "自動" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "浮動小数点" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "デコードしたそのまま" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "リプレイゲインの適用後" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "エフェクトの適用後" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "イコライザーの適用後" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "シャッフルの設定に合わせる" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "インターフェイス:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "出力プラグイン:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "すべてのファイルを増幅する:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "タグづけされていないファイルを増幅する:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "出力の設定" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "ビット深度:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "バッファーサイズ:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "ソフトクリッピング" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "ソフトウェアの音量コントロールを使う (非推奨)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "録音の設定" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "録音するストリーム:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "リプレイゲイン" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "リプレイゲインを有効にする" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "モード:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "クリッピングを防ぐ (非推奨)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "プロキシのホスト名:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "プロキシのポート:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "プロキシのユーザ名:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "プロキシのパスワード:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "ネットワークの設定" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "プロキシの設定" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "プロキシの使用を有効にする" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "プロキシの認証を行う" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "文字コードの自動検出対象言語:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "検出失敗時に試行する文字コード:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "動作" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "起動時に再生を再開する" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "再生せずに一時停止状態で起動" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "現在の曲が削除された時に次の曲を再生する" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "ファイルを開く時にプレイリストをクリアする" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "ファイルを一時プレイリストで開く" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "曲の表示" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "曲番号の表示" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "頭の0を表示する (例 02:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "時分秒表示を使う (例 1:30:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "エクスポート" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "可能な限り相対パスを使う" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "アルバムアート" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "次の単語にマッチする画像を検索する (コンマで区切る):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "次の単語にマッチする画像を除外する (コンマで区切る):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "曲のファイル名にマッチする画像を検索する" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "再帰的に検索する" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "検索の深さ:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "ポップアップ情報" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "ポップアップ情報を表示する" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "ポップアップの遅れ (10秒単位):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "現在の曲のタイムスケールを表示する" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "互換性" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "\\ (バックスラッシュ) をフォルダーの区切り文字として解釈する" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "プレイリスト" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "再帰的にフォルダーを追加する" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "プレイリスト内に入れ子にされたフォルダーを追加する" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "メタデータ" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "メタデータがないときにファイルパスから推定" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "再生が終わるまで曲のメタデータを読み込まない" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "ファイル拡張子が未知のときにはファイル内容を精査する" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "その他" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "秒" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "タイトル" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "タイトル - アーティスト" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "タイトル - アーティスト - アルバム" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "アーティスト - タイトル" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "アーティスト - アルバム - タイトル" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "アーティスト - アルバム - トラック. タイトル" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "アーティスト [ アルバム ] - トラック. タイトル" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "アルバム - タイトル" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "カテゴリー" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "カスタム" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "タイトルの書式:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "カスタム文字列:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "%sを使ってオーディオストリームを録音する" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "オーディオ録音プラグインを利用できません" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious の設定" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "キャンセル" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "保存" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "読み込み" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "プリセットファイルを読込む" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "EQF ファイルを読込む" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "プリセットファイルを保存" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "EQF ファイルを保存" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "キューマネージャー" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "キューからはずす(_U)" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "処理中 ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "エラー" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "情報" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "履歴に追加 (_S)" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "URL を開く" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "URL を追加" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "履歴を削除 (_L)" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "URL を入力:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "開く" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(追加のメッセージが隠れているかもしれません。)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "閉じる" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "参照" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "フォルダーを開く" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "フォルダーを追加" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "追加" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "メタデータ" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "作曲者" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "演者" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "制作年" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "制作日" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "技術情報" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "ビットレート" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "レベル:" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "機能" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "メッセージ" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "ログ検査" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "デバッグ" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "情報" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "警告" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "クリアー(_E)" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "ログレベル:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "サービス" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "コピー" diff --git a/po/ko.po b/po/ko.po new file mode 100644 index 0000000..d4ad6c8 --- /dev/null +++ b/po/ko.po @@ -0,0 +1,1512 @@ +# Korean translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# ChoSeongWoo , 2008 +# ChoSeongWoo , 2008 +# Seong-ho Cho , 2012-2014 +# natird zoto , 2012 +# Jaegeum Choe , 2001 +# kim suhyun , 2019 +# Man-Yong Lee , 2000 +# natird zoto , 2012 +# natird zoto , 2012 +# natird zoto , 2012 +# Sang-Jin Hwang , 1999 +# Seong-ho Cho , 2012 +# Seong-ho Cho , 2012-2015,2017 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Seong-ho Cho \n" +"Language-Team: Korean (http://www.transifex.com/audacious/audacious/language/ko/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ko\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "명령행 도움말 표시" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "버전 보기" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "재생 시작" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "재생 일시 정지" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "재생 중이면 일시 정지, 그 외에는 재생" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "재생 정지" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "이전 곡으로 건너뛰기" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "다음 곡으로 건너뛰기" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "재생 목록에 파일 추가" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "임시 재생 목록에 파일 추가" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "기본 창 표시" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "곡으로 건너뛰기 창 표시" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "그래픽 인터페이스를 제외하고 시작" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "재생을 끝나면 종료" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "디버깅 메시지 출력(두번 사용할 수 있음)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "알 수 없는 옵션: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "알 수 없는 옵션: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "사용법: audacious <옵션> ... <파일> ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "실행/제어할 인스턴스 선택" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "오데이셔스 " + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "파일 %d개를 찾았습니다" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "%s 읽기 오류:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "파일이 없습니다." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "새 재생 목록" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "표준 입력" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "음악 CD, %s 트랙" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(문자 인코딩 오류)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "스트림 녹음을 사용하려면 오디오 설정에서 설정해야합니다." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "출력 스트림 열기 오류" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "출력 스트림 녹음 오류" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "%s 재생 오류:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "잘못된 오디오 형식" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "재생 중" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "%s 열기 오류:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "%s 불러오는 중 오류." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "%s을(를) 불러올 수 없습니다: 지원하지 않는 파일 이름 확장자." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "%s을(를) 저장할 수 없습니다: 지원하지 않는 파일 이름 확장자." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "플러그인 불러오는 중 오류" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "탐색 오류" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "파일 형식을 인식할 수 없습니다" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "메타데이터 읽는 중 오류" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "모노" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "스테레오" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "채널 %d개" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "오디오 CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "%d번 트랙" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(알 수 없는 제목)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "알 수 없는 URI 형식" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "잘못된 파일 이름" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "잘못된 접근 모드" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "애써주신 분" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "라이선스" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "오데이셔스 정보" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "취소(_C)" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "다시 묻지 않음(_D)" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "“%s”을(를) 완전히 제거하시겠습니까?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "제거(_R)" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "재생 목록 제거" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "이 재생 목록을 호출하기 위해 무얼 하시겠습니까?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "이름 바꾸기(_R)" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "재생 목록 이름 바꾸기" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "프리셋 파일..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF 파일..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "가져오기" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "내보내기" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "이퀄라이저 프리셋" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "프리셋 저장" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "선택 항목 삭제" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "바뀐 항목 되돌리기" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "활성화(_E)" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "이퀄라이저" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "프리셋..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "0 값으로 초기화" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "프리앰프" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "파일 열기" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "열기(_O)" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "열 때 대화상자 닫기(_D)" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "파일 추가" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "추가(_A)" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "추가할 때 대화상자 닫기(_D)" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "닫기(_C)" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "제목" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "음악가" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "음반" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "장르" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "연도" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "트랙" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "길이" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "형식:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "품질:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "비트 전송율:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "애이시드 재즈" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "애이시드 락" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "앰비언트" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "비밥" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "블루글래스" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "블루스" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "쳄버 뮤직" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "클래식" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "컨트리" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "데스 메탈" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "디스코" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "이지 리스닝" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "포크" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "펑크" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "갱스터 랩" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "가스펠" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "그런지" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "하드 락" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "헤비메탈" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "힙합" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "하우스" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "재즈" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "정글" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "메달" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "뉴 에이지" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "뉴 웨이브" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "노이즈" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "팝" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "펑크 락" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "랩" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "레게" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "락" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "락 앤 롤" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "리듬 앤 블루스" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "스카" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "소울" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "스윙" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "테크노" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "트리팝" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "성공적으로 저장" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "저장 오류" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "곡 정보" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "앨범 음악가" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "주석" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "트랙 번호" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "저장(_S)" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "다음(_N)" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "없음" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "건너뛰기(_J)" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "시간 이동" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "시간 입력(분:초):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "대기열(_Q)" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "대기열 해제(_Q)" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "곡 건너뛰기" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "필터: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "필터(_F):" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "건너뛸 때 닫기(_L)" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "덮어쓰기(_O)" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "덮어쓰기 확인" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "%s을(를) 덮어쓰시겠습니까?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "파일 이름 확장자를 입력하거나 드롭다운 목록에서 형식을 선택하십시오." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "확장자로 형식 선택" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "재생 목록 내보내기" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "내보내기(_E)" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "재생 목록 가져오기" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "가져오기(_I)" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "플러그인(_P)..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "%s 정보" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s 설정" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "설정(_S)" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "설정(_S)" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "정보(_A)" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "파일 선택" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "폴더 선택" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "모양새" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "오디오" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "네트워크" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "재생 목록" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "플러그인" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "전문가모드" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "일반" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "효과" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "시각 효과" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "입력" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "전송" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "앨범 음악가" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "트랙 번호" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "파일 이름" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "파일 경로" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "날짜" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "코덱" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "음질" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "없음" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "아라비아어" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "발트 해 언어" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "중국어" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "그리스어" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "히브리어" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "일본어" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "한국어" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "폴란드어" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "러시아어" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "타이완어" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "터키어" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "자동" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "부동 소숫점" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "디코딩 상태" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "리플레이게인 적용" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "효과 적용" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "이퀄라이제이션 적용" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "임의 재생 기반" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "인터페이스" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "출력 플러그인:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "모든 파일 소리 증폭:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "태그가 붙지 않은 파일 증폭:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "출력 설정" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "비트 깊이:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "버퍼 크기:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "부드러운 클리핑" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "프로그램 음량 조절기 사용(추천하지 않음)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "녹음 설정" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "녹음 스트림:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "리플레이게인" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "리플레이게인 활성화" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "모드:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "클리핑 방지(추천)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "프록시 호스트 이름:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "프록시 포트:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "프록시 사용자 이름:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "프록시 암호:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "네트워크 설정" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "프록시 설정" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "프록시 사용" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "프록시에서 인증 사용" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "문자 인코딩 자동 감지기:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "대체할 문자 인코딩:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "동작" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "시작할 때 재생 상태 재개" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "즉시 재생 상태를 재개하는 대신 멈춤" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "현재 곡이 삭제되면 다음 곡으로 진행" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "파일을 열 때 재생 목록 지우기" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "임시 재생 목록에서 파일 열기" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "노래 표시" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "곡 번호 표시" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "자리수 맞추기 영(0) 표시(02:00 / 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "시간 단위 개별 표시(1:30:00 / 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "출력" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "가능할경우 상대적 경로를 사용합니다." + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "음반 표지" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "이 단어에 일치하는 그림 검색(콤마로 구분):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "이 단어에 일치하는 그림 제외(콤마로 구분):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "곡 파일 이름에 일치하는 그림 검색" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "재귀 검색" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "검색 깊이:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "팝업 정보" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "풍선 도움말 정보 표시" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "풍선 도움말 지연시간(10초 단위):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "현재 곡의 시간 길이 표시" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "호환성" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "\\ (역슬래시)를 폴더 구분자로 해석" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "재생목록" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "메타데이터" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "파일 경로로 빠진 메타데이터 추측" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "재생할 때 곡 메타데이터를 불러오기" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "파일 이름 확장자로 인힉할 수 없는 파일 내용 살펴보기" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "기타" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "초" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "제목" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "제목 - 음악가" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "제목 - 음악가 - 앨범" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "음악가 - 제목" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "음악가 - 음반 - 제목" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "음악가 - 음반 - 트랙. 제목" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "음악가 [ 음반 ] - 트랙. 제목" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "음반 - 제목" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "부문" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "사용자 정의" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "제목 형식:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "사용자 정의:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "%s 오디오 스트림 녹음 활성화" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "사용할 수 있는 오디오 녹음 플러그인이 없습니다" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "오데이셔스 설정" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "취소" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "저장" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "불러오기" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "프리셋 파일 불러오기" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "EQF 파일 불러오기" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "프리셋 파일 저장" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "EQF 파일 저장" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "대기목록 관리자" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "큐에서 빼내기(_U)" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "동작 중..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "오류" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "정보" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "실행기록 저장하기" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "URL 열기" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "URL 추가" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "실행기록 지우기" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "URL 입력:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "열기" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(이하 메시지는 숨겨져 있습니다.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "닫기" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "찾아보기" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "폴더 열기" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "폴더 추가" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "추가" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "메타데이터" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "작곡가" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "연주자" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "음반 제작연도" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "음반 제작일자" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "기술 사항" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "비트 전송율" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "레벨" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "함수" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "메시지" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "로그 감시기" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "디버그" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "정보" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "경고" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "지우기(_E)" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "기록 수준:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "서비스" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "복사" diff --git a/po/lt.po b/po/lt.po new file mode 100644 index 0000000..1f61ec7 --- /dev/null +++ b/po/lt.po @@ -0,0 +1,1511 @@ +# Lithuanian translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# <>, 2012 +# Algimantas Margevičius , 2011-2014 +# Algimantas Margevičius , 2011, 2012 +# Algimantas Margevičius , 2011-2012 +# Algimantas Margevičius , 2011 +# Rimas Kudelis , 2004 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: John Lindgren \n" +"Language-Team: Lithuanian (http://www.transifex.com/audacious/audacious/language/lt/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: lt\n" +"Plural-Forms: nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Rodyti komandinės eilutės pagalbą" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Rodyti versiją" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Pradėti atkūrimą" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pristabdyti atkūrimą" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pristabdyti, jei grojama, kitu atveju groti" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Sustabdyti atkūrimą" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Ankstesnė daina" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Kita daina" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Pridėti failus į grojaraštį" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Pridėti failus į laikiną grojaraštį" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Parodyti pagrindinį langą" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Rodyti perėjimo prie dainos langą" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Paleisti be grafinės sąsajos" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Sustabdžius atkūrimą baigti" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Nežinomas parametras: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Nežinomas parametras: %c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Naudojimas: [PARAMETRAS]... [FAILAS]...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d failas rastas" +msgstr[1] "%d failai rasti" +msgstr[2] "%d failų rasti" +msgstr[3] "%d failų rasti" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "" + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Naujas grojaraštis" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Audio CD, takelis %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Dabar grojama" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanalas" +msgstr[1] "%d kanalai" +msgstr[2] "%d kanalų" +msgstr[3] "%d kanalų" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Audio CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Takelis %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Padėkos" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licencija" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Apie Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Atsisakyti" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Daugiau nebeklausti" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Ar tikrai norite visam laikui pašalinti „%s“?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Pašalinti" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Pašalinti grojaraštį" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Kaip pavadinsite šį grojaraštį?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Pervadinti" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Pervadinti grojaraštį" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importuoti" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Eksportuoti" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Įjungtas" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Ekvalaizeris" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "" + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Atstatyti nulį" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamp" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Atverti failus" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Atverti" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Atvėrus, užverti _dialogą" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Pridėti failus" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Pridėti" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Pridėjus, užverti _dialogą" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Užverti" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Pavadinimas" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Atlikėjas" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Albumas" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Žanras" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Metai" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Takelis" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Trukmė" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formatas:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Kokybė:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bitų dažnis:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebob" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Chamber Music" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Classical" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-Hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-Hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Sėkmingai išsaugota" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Įrašymo klaida" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Dainos informacija" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Komentaras" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Dainos numeris" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Įrašyti" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Sekantis" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/A" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Šokti " + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Šokti į laiką" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Įveskite laiką (minutės:sekundės):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Į eilę" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Iš _eilės" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Peršokti į dainą" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtruoti:" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtruoti:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Užverti peršokus" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "P_errašyti" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Patvirtinkite perrašymą" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Perrašyti %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Eksportuoti grojaraštį" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Eksportuoti" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Įkrauti grojaraštį" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importuoti" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Įskiepiai..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Apie %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s nustatymai" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Nustatyti" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Nustatymai" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Apie" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Pasirinkite aplanką" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Išvaizda" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Garsas" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Tinklas" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Grojaraštis" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Įskiepiai" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Pagrindiniai" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efektai" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Vizualizacija" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Įvestis" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transportas" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Bylos vardas" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Bylos kelias" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Data" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Kodekas" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Kokybė" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Joks" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arabų" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltijos" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Kinų" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Graikų" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebrajų" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japonų" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Korėjiečių" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Lenkų" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Rusų" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taivaniečių" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turkų" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Slankiojantis taškas" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Išvesties įskiepis:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Pagarsinti visus failus:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Pagarsinti failus be žymių:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Išvesties nustatymai" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Nominalus bitų sekos greitis:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Buferio dydis (kb):" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Lengvas apkrapymas" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Naudoti programinį garso valdymą (nerekomenduojama)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Uždrausti apkarpymą (rekomenduojama)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Tarpinis serveris:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Tarpinio serverio prievadas:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Tarpinio serverio naudotojas:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Tarpinio serverio slaptažodis:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Tarpinio serverio nustatymai" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Leisti naudoti tarpinį serverį" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Su tarpiniu serveriu naudoti tapatybės nustatymą" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automatinis koduotės nustatymas:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Atsarginis kodavimas:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Elgsena" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Kai pasirinkta daina ištrinama, žengti į priekį" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Kai atveriamas failas, išvalyti grojaraštį" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Atverti failus laikiname grojaraštyje" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Kūrinio pavadinimo vaizdavimas" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Rodyti dainos numerį" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Albumo apivadalinimas" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Ieškoti paveikslėlių kurie atitinka šiuos žodžius (atskirti kableliais):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Išskirti žodžius atitinkančius šiuos žodžius (atskirti kableliais):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Ieškoti paveikslėlių atitinkančių dainos failo vardą" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Ieškoti rekursyviai" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Paieškos gylis:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Iššokančio lango informacija" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Rodyti iššokantį informacijos langą" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Iššokančio lango rodymo trukmė(dešimtimis sekundžių):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Rodyti grojančios dainos laiko juostą" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Suderinamumas" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Laikyti \\ (įžambinį kairįjį brūkšnį) aplanko skirtuku" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Meta duomenys" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Kol negrojama, dainom neįkrauti meta duomenų" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Kita" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "sekundės" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "PAVADINIMAS" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ATLIKĖJAS - PAVADINIMAS" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ATLIKĖJAS - ALBUMAS - PAVADINIMAS" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ATLIKĖJAS - ALBUMAS - TAKELIS. PAVADINIMAS" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ATLIKĖJAS [ ALBUMAS ] - TAKELIS. PAVADINIMAS" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUMAS - PAVADINIMAS" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategorija" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Pasirinktinė" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Pavadinimo formatas:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Pasirinktinė eilutė:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious nustatymai" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Atsisakyti" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Išsaugoti" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Įkrauti" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Įkrauti šabloną iš failo" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Įkelti EQF failą" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Išsaugoti šabloną į failą" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Išsaugoti šabloną į EQF failą" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Eilės redaktorius" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Iš eilės" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "" + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Klaida" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Atverti URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Pridėti URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Įveskite URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Atverti" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Sekantys pranešimai paslėpti.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Užverti" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Naršyti" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bitų seka" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Įspėjimas" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Tarnybos" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopijuoti" diff --git a/po/lv.po b/po/lv.po new file mode 100644 index 0000000..40a8f48 --- /dev/null +++ b/po/lv.po @@ -0,0 +1,1506 @@ +# Latvian translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# hairy_latvian , 2014-2016 +# hairy_latvian , 2009, 2011, 2012 +# hairy_latvian , 2009,2011-2014 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: John Lindgren \n" +"Language-Team: Latvian (http://www.transifex.com/audacious/audacious/language/lv/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: lv\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Parādīt komandrindas palīdzību" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Parādīt versiju" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Sākt atskaņošanu" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pauzēt atskaņošanu" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Nopauzēt, ja pašlaik atskaņo, citādi atskaņot" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Apturēt atskaņošanu" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Pāriet uz iepriekšējo dziesmu" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Pāriet uz nākamo dziesmu" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Pievieno failus repertuāram" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Pievienot jaunus failus pagaidu repertuāram" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Rādīt galveno logu" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Rādīt logu 'pāriet uz dziesmu'" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Palaist bez grafiskās saskarnes" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Iziet, kad beidzas atskaņošana" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Drukāt atkļūdošanas ziņojumus (var tikt izmantots divas reizes)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Nezināma opcija: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Nezināma opcija: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Lietošana: audacious [OPCIJA] ... [FAILS] ...\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Izvēlēties palaižamo/vadāmo instanci" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Atrasts %d fails" +msgstr[1] "Atrasti %d faili" +msgstr[2] "Atrasti %d faili" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Kļūda lasot %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Faili netika atrasti." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Jauns repertuārs" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Standarta ievade" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Audio CD, %s. celiņš" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(rakstzīmju kodēšanas kļūda)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Kļūda atverot izvades straumi" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Kļūda atskaņojot %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Nederīgs audio formāts" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Pašreiz atskaņo" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Kļūda atverot %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Kļūda ielādējot %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Neizdevās ielādēt %s: neatbalstīts faila paplašinājums." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Neizdevās saglabāt %s: neatbalstīts faila paplašinājums." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Kļūda ielādējot spraudni" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Meklēšanas kļūda" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Faila formāts nav atpazīts" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Kļūda lasot metadatus" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanāls" +msgstr[1] "%d kanāli" +msgstr[2] "%d kanālu" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Audio CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Celiņš %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(nezināms nosaukums)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Nezināma URI shēma" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Nederīgs faila nosaukums" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Nederīgs piekļūšanas režīms" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Izstrādātāji" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licence" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Par Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "At_celt" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Nejautāt vēlreiz" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Vai vēlaties uz visiem laikiem izņemt \"%s\"?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Izņemt" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Izņemt repertuāru" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Kā jūs vēlētos nosaukt šo repertuāru?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "Pā_rdēvēt" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Pārdēvēt repertuāru" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Sākumuzstādījumu fails ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF fails ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importēt" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Eksportēt" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Balansiera sākumuzstādījumi" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Saglabāt sākumuzstādījumu" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Dzēst izvēlētos" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Atcelt izmaiņas" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Ieslēgts" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Equalizer" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Sākumuzstādījumi ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Atstatīt uz nulli" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Priekšpastiprinājums" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Atvērt failus" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Atvērt" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Atverot aizvērt _dialoglogu" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Pievienot failus" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "Pi_evienot" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Pievienojot aizvērt _dialoglogu" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Aizvērt" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Nosaukums" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Izpildītājs" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Albums" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Žanrs" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Gads" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Celiņš" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Ilgums" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formāts:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Kvalitāte:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bitātrums:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blūzs" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Chamber Music" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klasiskā mūzika" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Kantrī" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disko" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Džezs" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pops" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Pankroks" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Reps" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Regejs" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Roks" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Tehno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Saglabāšana veiksmīga" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Saglabāšanas kļūda" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Dziesmas info" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Albuma izpildītājs" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Komentārs" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Celiņa numurs" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Saglabāt" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Nākamā" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/P" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "Pār_iet" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Pāriet uz laiku" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Ievadiet laiku (minūtes:sekundes)" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "Ierindot" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Atrindot" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Pāriet uz dziesmu" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtrs: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtrs:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "A_izvērt pārejot" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "Pārra_kstīt" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Apstiprināt pārrakstīšanu" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Pārrakstīt %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Lūdzu, ievadiet faila paplašinājumu vai izvēlieties formātu no izkrītošā saraksta" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Izvēlieties formātu pēc paplašinājuma" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Eksportēt repertuāru" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Eksportēt" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importēt repertuāru" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importēt" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "S_praudņi ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Par %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s iestatījumi" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "Ie_statīt" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "I_estatījumi" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Par" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Izvēlieties failu" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Izvēlieties mapi" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Izskats" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Skaņa" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Tīkls" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Repertuārs" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Spraudņi" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Vispārīgi" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efekti" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Vizualizēšana" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Ievade" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transports" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Albuma izpildītājs" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Celiņa numurs" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Faila nosaukums" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Faila ceļš" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Datums" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Kodeks" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Kvalitāte" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Neviens" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arābu" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltu" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Ķīniešu" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Grieķu" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Ebreju" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japāņu" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Korejiešu" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Poļu" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Krievu" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taivānu" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turku" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automātiski" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Peldošā punkta" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Kā atkodēts" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Pēc ReplayGain pielietošanas" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Pēc efektu pielietošanas" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Pēc balansēšanas pielietošanas" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Izvades spraudnis:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Pastiprināt visus failus:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Pastiprināt netagotos failus:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Izvades iestatījumi" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bitu dziļums:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Bufera izmērs:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "'Mīkstā' apgriešana" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Lietot programmatūras skaļuma kontroli (nav ieteicams)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Ieraksta iestatījumi" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Ieraksta straume:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Ieslēgt ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Novērst apgriešanu (ieteicams)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Starpniekservera nosaukums:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Starpniekservera ports:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Starpniekservera lietotājvārds:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Starpniekservera parole:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Tīkla iestatījumi" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Starpniekservera konfigurācija" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Ieslēgt starpniekservera izmantošanu" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Savienojoties ar starpniekserveri, izmantot autentificēšanos" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automātiska rakstzīmju kodējuma noteikšana priekš:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Atkāpšanās rakstzīmju kodējumi:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Izturēšanās" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Palaižot turpināt atskaņošanu" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pauzēt nevis uzreiz atsākt" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Iet uz priekšu, ja pašreizējā dziesma tiek dzēsta" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Atverot failus, notīrīt repertuāru" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Atvērt failus pagaidu repertuārā" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Dziesmu attēlojums" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Rādīt dziesmu numurus" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Rādīt ievadošās nulles (02:00 nevis 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Stundas rādīt atsevišķi (1:30:00 nevis 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Albuma vāks" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Meklēt attēlus, kuri atbilst šiem vārdiem (atdalītiem ar komatu):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Neiekļaut attēlus, kuri atbilst šiem vārdiem (atdalītiem ar komatu):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Meklēt attēlus, kas atbilst dziesmas faila nosaukumam" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Meklēt rekursīvi" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Meklēšanas dziļums:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Izlecošā informācija" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Rādīt izlecošo informāciju" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Izlecošā loga aizture (sekundes desmitdaļas):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Rādīt laika mērogu pašreizējai dziesmai" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Savietojamība" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpretēt \\ (otrādo slīpsvītru) kā mapju atdalītāju" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadati" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Minēt trūkstošos metadatus no faila ceļa" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Neielādēt metadatus, līdz dziesma tiek atskaņota" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Testēt failus ar neatpazītiem failu paplašinājumiem" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Dažādi" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "sekundes" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "NOSAUKUMS" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "NOSAUKUMS - IZPILDĪTĀJS" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "NOSAUKUMS - IZPILDĪTĀJS - ALBUMS" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "IZPILDĪTĀJS - NOSAUKUMS" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "IZPILDĪTĀJS - ALBUMS - NOSAUKUMS" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "IZPILDĪTĀJS - ALBUMS - CELIŅŠ. NOSAUKUMS" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "IZPILDĪTĀJS [ ALBUMS ] - CELIŅŠ. NOSAUKUMS" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUMS - NOSAUKUMS" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategorija" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Pielāgots" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Nosaukuma formāts:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Pielāgota virkne:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Audio ierakstīšanas spraudnis nav pieejams" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious iestatījumi" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Atcelt" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Saglabāt" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Ielādēt" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Ielādēt sākumuzstādījumu failu" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Ielādēt EQF failu" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Saglabāt sākumuzstādījumu failu" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Saglabāt EQF failu" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Rindas pārvaldnieks" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Izņemt no rindas" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Darbojas ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Kļūda" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Informācija" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Atvērt URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Pievienot URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Ievadiet URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Atvērt" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Turpmākie ziņojumi tika paslēpti.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Aizvērt" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Pārlūkot" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Atvērt mapi" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Pievienot mapi" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Pievienot" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadati" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Komponists" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Izpildītājs" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Ierakstīšanas gads" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Ierakstīšanas datums" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Tehniskie" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bitātrums" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Līmenis" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Funkcija" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Ziņojums" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Žurnāla inspektors" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Atkļūdot" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Informācija" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Brīdinājums" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Žurnāla līmenis:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Servisi" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopēt" diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 0000000..e05db57 --- /dev/null +++ b/po/meson.build @@ -0,0 +1,15 @@ +i18n = import('i18n') + + +i18n.gettext('audacious', + args: [ + '--default-domain=audacious', + '--language=C', + '--keyword=_', + '--keyword=N_', + '--from-code=UTF-8', + '--msgid-bugs-address="https://redmine.audacious-media-player.org/"', + '--directory=%0%'.format(meson.source_root()), + '--files-from=POTFILES.in' + ] +) diff --git a/po/ml_IN.po b/po/ml_IN.po new file mode 100644 index 0000000..637547f --- /dev/null +++ b/po/ml_IN.po @@ -0,0 +1,1504 @@ +# Malayalam (India) translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# <>, 2013 +# Nandakumar , 2013 +# Nandakumar , 2013 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Navaneeth \n" +"Language-Team: Malayalam (India) (http://www.transifex.com/audacious/audacious/language/ml_IN/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ml_IN\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "പതിപ്പ് കാണിയ്ക്കുക" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "പാടുകയാണെങ്കില്‍ പോസ് ചെയ്യുക, അല്ലെങ്കില്‍ പാടുക" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "പ്ലേലിസ്റ്റിലേയ്ക്ക് ഫയലുകള്‍ ചേര്‍ക്കുക" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "മുഖ്യജാലകം പ്രദര്‍ശിപ്പിയ്ക്കുക" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "പാട്ടുനിന്നാല്‍ പുറത്തുകടക്കുക" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "ഒഡാഷ്യസ്" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d ഫയല്‍ കണ്ടെത്തി" +msgstr[1] "%d ഫയലുകള്‍ കണ്ടെത്തി" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "" + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "പുതിയ പ്ലേലിസ്റ്റ്" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "ഓഡിയോ സി.ഡി., ട്രാക്ക് %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "ഇപ്പോള്‍ പാടുന്നത്" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "മോണോ" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "സ്റ്റീരിയോ" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d ചാനല്‍" +msgstr[1] "%d ചാനലുകള്‍" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "ഓഡിയോ സി.ഡി." + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "ബഹുമതികള്‍" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "അനുമതിപത്രം" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "ഒഡാഷ്യസ്സിനെപ്പറ്റി" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_പേര് മാറ്റുക" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "പ്ലേലിസ്റ്റിന്റെ പേര് മാറ്റുക" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "ഇറക്കുമതി ചെയ്യുക" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_സാദ്ധ്യമാക്കുക" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "ഈക്വലൈസര്‍" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "" + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "പ്രീ‌ആംപ്" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "ഫയലുകള്‍ തുറക്കുക" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "ഫയലുകള്‍ ചേര്‍ക്കുക" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_അടയ്ക്കുക" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "ടൈറ്റില്‍" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "ആര്‍ട്ടിസ്റ്റ്" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "ആല്‍ബം" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "തരം" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "വര്‍ഷം" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "ട്രാക്ക്" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "നീളം" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "ഫോര്‍മാറ്റ്:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "ഗുണമേന്മ:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "ആസിഡ് ജാസ്" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "ആസിഡ് റോക്ക്" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "ആംബിയന്റ്" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "ബിബോപ്" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "ബ്ലൂഗ്രാസ്" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "ബ്ലൂസ്" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "ചേംബര്‍ മ്യൂസിക്" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "ക്ലാസിക്കല്‍" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "കണ്‍ട്രി" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "ഡെത്ത് മെറ്റല്‍" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "ഡിസ്കോ" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "ഈസി ലിസണിങ്" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "നാടോടി" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "ഫങ്ക്" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "ഗങ്സ്താ റാപ്പ്" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "ഗോസ്പല്‍" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "ഗ്രങ്" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "ഹാഡ് റോക്ക്" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "ഹെവി മെറ്റല്‍" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "ഹിപ്-ഹോപ്പ്" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "വീട്" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "ജാസ്" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "കാട്" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "മെറ്റല്‍" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "നവയുഗം" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "നവതരംഗം" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "ശബ്ദം" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "പോപ്പ്" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "പങ്ക് റോക്ക്" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "റാപ്പ്" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "റെഗ്ഗേജ്" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "റോക്ക്" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "റോക്ക് ആന്‍ഡ് റോള്‍" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "റിഥം ആന്‍ഡ് ബ്ലൂസ്" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "സ്കാ" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "സോള്‍" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "സ്വിങ്" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "ടെക്നോ" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "ട്രിപ്പ്-ഹോപ്പ്" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "സോങ് ഇന്‍ഫോ" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "അഭിപ്രായം" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_അടുത്തത്" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "സമയത്തിലേയ്ക്ക് ചാടുക" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "സമയം നല്‍കുക (മിനിറ്റുകള്‍:സെക്കന്‍ഡുകള്‍)" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_ക്യൂ" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "അ_ണ്‍ക്യൂ" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "പാട്ടിലേയ്ക്ക് ചാടുക" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "അരിപ്പ:" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_അരിപ്പ:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "മായ്ച്ചെഴുതണോ: %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "പ്ലേലിസ്റ്റ് കയറ്റുമതി ചെയ്യുക" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "പ്ലേലിസ്റ്റ് ഇറക്കുമതി ചെയ്യുക" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "" + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "%s-നെപ്പറ്റി" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s ക്രമീകരണങ്ങള്‍" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "ഫോള്‍ഡര്‍ തെരെഞ്ഞെടുക്കുക" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "ഓഡിയോ" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "നെറ്റ്‌വര്‍ക്ക്" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "പ്ലേലിസ്റ്റ്" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "പ്ലഗ്ഗിന്നുകള്‍" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "പൊതുവായ" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "പ്രഭാവം" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "ദൃശ്യവത്കരണം" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "ഇന്‍പുട്ട്" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "കടത്തുക" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "ഫയല്‍ നെയിം" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "ഫയല്‍ പാത്ത്" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "തീയതി" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "കോഡെക്" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "ഗുണമേന്മ" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "ശൂന്യം" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "അറബിക്" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "ബാള്‍ട്ടിക്" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "ചൈനീസ്" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "ഗ്രീക്ക്" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "ഹീബ്രൂ" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "ജാപ്പനീസ്" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "കൊറിയന്‍" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "പോളിഷ്" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "റഷ്യന്‍" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "തായ്‌വാനീസ്" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "ടര്‍ക്കിഷ്" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "ഫ്ലോട്ടിങ് പോയിന്റ്" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "ഔട്പുട്ട് പ്ലഗ്ഗിന്‍" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "എല്ലാ ഫയലുകളും ആംപ്ലിഫൈ ചെയ്യുക" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "അണ്‍ടാഗ്ഡ് ഫയലുകള്‍ ആംപ്ലിഫൈ ചെയ്യുക:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "ഔട്പുട്ട് ക്രമീകരണങ്ങള്‍" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "ബിറ്റ് ഡെപ്ത്" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "ബഫര്‍ സൈസ്" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "സോഫ്റ്റ് ക്ലിപ്പിങ്" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "സോഫ്റ്റ്‌വെയര്‍ ശബ്ദനിയന്ത്രണോപാധി ഉപയോഗിയ്ക്കുക (ശുപാര്‍ശ ചെയ്യപ്പെട്ടിട്ടില്ല)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "ക്ലിപ്പിങ് തടയുക (ശുപാര്‍ശ ചെയ്യപ്പെട്ടത്)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "പ്രോക്സി ഹോസ്റ്റ്നെയിം:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "പ്രോക്സി പോര്‍ട്ട്" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "പ്രോക്സി ഉപയോക്തൃനാമം" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "പ്രോക്സി അടയാളവാക്യം" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "പ്രോക്സി ക്രമീകരണം" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "പ്രോക്സി ഉപയോഗം സാദ്ധ്യമാക്കുക" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "പ്രോക്സി ഉപയോഗിച്ചുകൊണ്ടുള്ള ഓതന്റിക്കേഷന്‍ സാദ്ധ്യമാക്കുക" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "ഇതിനായി ഓട്ടോ ക്യാരക്റ്റര്‍ എന്‍കോഡിങ് ഡിറ്റക്റ്റര്‍:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "ഫാള്‍ബാക്ക് ക്യാരക്റ്റര്‍ എന്‍കോഡിങ്ങുകള്‍:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "സ്വഭാവം" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "ഈ പാട്ട് ഡിലീറ്റായാല്‍ മുന്നോട്ടുനീങ്ങുക" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "ഫയലുകള്‍ തുറക്കുമ്പോള്‍ പ്ലേലിസ്റ്റ് വെടിപ്പാക്കുക" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "ഫയലുകള്‍ ഒരു താത്കാലികപ്ലേലിസ്റ്റില്‍ തുറക്കുക" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "സോങ് ഡിസ്പ്ലേ" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "പാട്ടുനമ്പറുകള്‍ കാണിയ്ക്കുക" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "ആല്‍ബം ആര്‍ട്ട്" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "ഈ വാക്കുകള്‍ക്കു യോജിച്ച ചിത്രങ്ങള്‍ക്കായി തിരയുക (കോമയാല്‍ വേര്‍തിരിയ്ക്കപ്പെട്ടത്)" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "ഈ വാക്കുകള്‍ക്കു യോജിച്ച ചിത്രങ്ങള്‍ ഒഴിവാക്കുക (കോമയാല്‍ വേര്‍തിരിയ്ക്കപ്പെട്ടത്)" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "പാട്ടിന്റെ ഫയല്‍ നെയിമിന് യോജിച്ച ചിത്രങ്ങള്‍ക്കായി തിരയുക" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "റിക്കര്‍സീവ് ആയി തിരയുക" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "സേര്‍ച്ച് ഡെപ്ത്:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "പോപ്പപ്പ് വിവരം" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "പോപ്പപ് വിവരം പ്രദര്‍ശിപ്പിയ്ക്കുക" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "പോപ്പപ്പ് വൈകല്‍ (ഒരു സെക്കന്‍ഡിന്റെ പത്തിലൊന്നുകള്‍)" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "ഈ പാട്ടിന്റെ ടൈം സ്കെയില്‍ കാണിയ്ക്കുക" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "അനുയോഗ്യത" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "\\ (backward slash) -നെ ഒരു ഫോള്‍ഡര്‍ ഡീലിമിറ്റര്‍ ആയി വ്യാഖ്യാനിയ്ക്കുക" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "മെറ്റാഡേറ്റ" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "പാട്ടുകള്‍ പാടുന്നതുവരെ മെറ്റാഡാറ്റ ലോഡ് ചെയ്യേണ്ട" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "പലവക" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "സെക്കന്‍ഡുകള്‍" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TITLE" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTIST - TITLE" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTIST - ALBUM - TITLE" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTIST - ALBUM - TRACK. TITLE" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTIST [ ALBUM ] - TRACK. TITLE" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - TITLE" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "വിഭാഗം" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "സ്വേച്ഛയാലുള്ള" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "ടൈറ്റില്‍ ഫോര്‍മാറ്റ്:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "സ്വേച്ഛയാലുള്ള എഴുത്ത്:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "റദ്ദാക്കുക" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "സേവ്" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "ലോഡ് ചെയ്യുക" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "ക്യൂ മാനേജര്‍" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "" + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "പിശക്" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "യൂ.ആര്‍.എല്‍. തുറക്കുക" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "യൂ.ആര്‍.എല്‍. ചേര്‍ക്കുക" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "യൂ.ആര്‍.എല്‍. നല്‍കുക:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(തുടര്‍ന്നുള്ള സന്ദേശങ്ങള്‍ മറച്ചുവച്ചിരിയ്ക്കുന്നു.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "തിരയുക" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "ബിറ്റ്‌റേറ്റ്" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "പകര്‍ത്തുക" diff --git a/po/ms.po b/po/ms.po new file mode 100644 index 0000000..af21a1d --- /dev/null +++ b/po/ms.po @@ -0,0 +1,1503 @@ +# Malay translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# abuyop , 2014 +# abuyop , 2014-2018 +# Mick The KN , 2012 +# Mick The KN , 2012 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Mick The KN \n" +"Language-Team: Malay (http://www.transifex.com/audacious/audacious/language/ms/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ms\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Tunjuk bantuan baris-perintah" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Tunjuk versi" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Mula main balik" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Jeda main balik" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Jeda jika bermain, main sebaliknya" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Henti main balik" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Langkau ke lagu terdahulu" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Langkau ke lagu berikutnya" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Tambah fail ke senarai main" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Tambah fail ke senarai main sementara" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Papar tetingkap utama" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Papar tetingkap lompat-ke-lagu" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Mula tanpa antaramuka bergrafik" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Keluar bila main balik berhenti" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Cetak mesej penyahpepijatan (mungkin diguna sebanyak dua kali)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Pilihan tidak diketahui: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Pilihan tidak diketahui: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Penggunaan: audacious [PILIHAN] ... [FAIL] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Pilih kejadian untuk jalan/kawal" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d fail ditemui" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Ralat membaca %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Tiada fail ditemui." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Senarai Main Baharu" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Input piawai" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Audio CD, track %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(ralat pengekodan aksara)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Rakaman strim mesti dikonfigur dalam Tetapan Audio sebelum ia boleh digunakan." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Ralat membuka strim output" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Ralat merakam strim output" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Ralat memainkan %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Format audio tidak sah" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Kini Dimainkan" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Ralat membuka %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Ralat memuatkan %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Tidak dapat muatkan %s: sambungan nama fail tidak disokong." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Tidak dapat simpan %s: sambungan nama fail tidak disokong." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Ralat memuatkan pemalam" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Ralat jangkau" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Format fail tidak dikenali" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Ralat membaca data meta" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d saluran" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "CD Audio" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Trek %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(tajuk tidak diketahui)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Skema URI tidak diketahui" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Nama fail tidak sah" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Mod capai tidak sah" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Kredit" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Lesen" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Tentang Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Batal" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Jangan tanya lagi" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Anda mahu buang \"%s\" secara kekal?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Buang" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Buang Senarai Main" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Apa yang anda mahu namakan senarai main ini?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Nama semula" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Namakan Semula Senarai Main" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Fail praset ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Fail EQF ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Import" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Eksport" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Praset Penyama" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Simpan Praset" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Padam Terpilih" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Kembalikan Perubahan" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Aktifkan" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Equalizer" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Praset ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Tetap Semula ke Sifar" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamp" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Buka Fail" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Buka" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Tutup _dialog bila dibuka" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Menambah Fail" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "T_ambah" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Tutup _dialog bila ditambah" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "T_utup" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Tajuk" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artis" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Genre" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Tahun" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Track" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Panjang" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Format:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Kualiti:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Kadar bit:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Jazz Asid" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Rock Asid" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Chamber Music" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Classical" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm dan Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Berjaya disimpan" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Ralat simpan" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Maklumat Lagu" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Album Artis" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Ulasan" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Nombor Trek" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Simpan" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Berikutnya" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "T/A" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Lompat" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Lompat ke Masa" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Masukkan masa (minit:saat):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Atur" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Tidak_Atur" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Lompat ke Lagu" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Tapis:" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Tapis:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "T_utup bila lompat" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "T_ulis Ganti" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Sahkan Tulis Ganti" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Tulisganti %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Sila taip sambungan nama fail atau pilih satu format dari senarai tarik-turun." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Pilih Format mengikut Sambungan" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Eksport Senarai Main" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Eksport" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Import Senarai Main" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Import" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Pemalam ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Perihal %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Tetapan %s" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Tetapkan" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Tetapan" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "Perih_al" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Pilih Fail" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Pilih Folder" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Penampilan" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Audio" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Rangkaian" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Senarai Main" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Pemalam" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Lanjutan" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Am" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Kesan" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Pengvisualan" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Input" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Pindah" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Artis album" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Nombor trek" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nama fail" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Laluan fail" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Tarikh" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Kodeks" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Kualiti" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Tiada" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Bahasa Arab" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Bahasa Baltik" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Bahasa Cina" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Bahasa Yunani" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Bahasa Ibrani" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Bahasa Jepun" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Bahasa Korea" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Bahasa Poland" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Bahasa Rusia" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Bahasa Taiwan" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Bahasa Turki" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automatik" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Titik terapung" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Seperti dinyahkod" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Selepas melaksana GandaanMainSemula" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Selepas melaksanakan kesan" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Selepas melaksanakan penyamaan" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Berdasarkan kocok" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Antaramuka:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Pemalam output:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Kuatkan semua fail:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Kuatkan fail tidak bertanda:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Tetapan Output" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Kedalaman bit:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Saiz penimbal:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "pengeratan lembut" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Guna perisian kawalan volum (tidak disarankan)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Tetapan Rakaman" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Rakam strim:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "GandaanMainSemula" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Benarkan GandaanMainSemula" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Mod:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Halang pengeratan (disaran)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Nama hos proksi:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Port proksi:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Nama pengguna proksi:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Kata laluan proksi:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Tetapan Rangkaian" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Konfigurasi Proksi" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Benarkan penggunaan proksi" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Guna pengesahihan dengan proksi" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Pengesan pengekodan aksara berautomatik untuk:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Pengekodan aksara jatuh balik:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Kelakuan" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Sambung main balik ketika permulaan" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Jeda selain dari sambung serta-merta" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Lanjutkan bila lagu semasa dipadam" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Kosongkan senarai main bila membuka fail" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Buka fail dalam senarai main sementara" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Paparan Lagu" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Tunjuk nombor lagu" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Tunjuk sifar dihadapan (02:00 bukan 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Tunjuk jam secara berasingan (1:30:00 bukan 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Eksport" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Guna laluan relatif jika boleh" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Seni Album" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Gelintar imej sepadan dengan perkataan ini (dipisah dengan tanda koma):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Tidak termasuk imej yang sepadan dengan kata (dipisah dengan koma):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Carian untuk imej lagu sepadan dengan nama fail" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Cari secara rekursif" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Cari dalaman:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Maklumat Timbul" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Menunjukkan maklumat popup" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Kelewatan popup (persepuluh sesaat):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Tunjukkan skala masa untuk lagu semasa" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Keserasian" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Tafsirkan \\ (miring belakang) sebagai penyahbatas folder" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Senarai Main" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Tambah folder secara rekursif" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Tambah folder tersarang di dalam fail senarai main" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Data meta" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Teka data meta yang hilang dari laluan fail" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Jangan muatkan data meta lagu sehingga dimainkan" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Kuar kandungan fail tanpa sambungan nama fail dikenali" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Pelbagai" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "Saat" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TAJUK" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TAJUK - ARTIS" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TAJUK - ARTIS - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTIST - TAJUK" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTIST - ALBUM - TAJUK" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTIST - ALBUM - TRACK. TAJUK" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTIST [ ALBUM ] - TRACK. TAJUK" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - TAJUK" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategori" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Custom" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Tajuk format:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Rentetan custom:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Benarkan rakaman strim audio dengan %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Tiada pemalam rakaman audio tersedia" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Tetapan Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Batal" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Simpan" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Muat" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Muat Fail Praset" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Muat Fail EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Simpan Fail Praset" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Simpan Fail EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Pengurus Teratur" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "N_yah Baris Gilir" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Bekerja ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Ralat" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Maklumat" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Simpan ke sejarah" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Buka URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Menambah URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "K_osongkan sejarah" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Masukkan URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Buka" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Mesej lanjut telah disembunyi.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Carian" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Buka Folder" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Tambah Folder" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Tambah" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Data meta" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Penggubah" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Penyampai" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Tahun Rakaman" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Tarikh Rakaman" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Teknikal" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Kadar bit" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Aras" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Fungsi" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Mesej" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Pemeriksa Log" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Nyahpepijat" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Maklumat" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Amaran" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "K_osongkan" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Aras Log:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Perkhidmatan" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Salin" diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 0000000..eab3f6c --- /dev/null +++ b/po/nl.po @@ -0,0 +1,1509 @@ +# Dutch translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Bjorn Roesbeke , 2012-2013 +# Dennis Klomp , 2012 +# dragnadh, 2015,2017 +# Farioko , 2014 +# Farioko , 2014 +# Glennz , 2012 +# Glennz , 2012 +# Heimen Stoffels , 2018,2020 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-27 11:47+0000\n" +"Last-Translator: Heimen Stoffels \n" +"Language-Team: Dutch (http://www.transifex.com/audacious/audacious/language/nl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: nl\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Opdrachtregelhulp tonen" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Versie tonen" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Afspelen starten" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Afspelen pauzeren" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pauzeren tijdens spelen, anders afspelen" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Afspelen stoppen" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Naar het vorige nummer" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Naar het volgende nummer" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Voeg bestanden toe aan de afspeellijst" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Voeg bestanden toe aan een tijdelijke afspeellijst" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Toon het hoofdvenster" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Toon het spring-naar-nummer-venster" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Start zonder een grafische interface" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Afsluiten bij stoppen met afspelen" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Foutopsporingsberichten tonen (kan tweemaal gebruikt worden)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Draaien in GTK-modus" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Onbekende optie: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Onbekende optie: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Gebruik: audacious [OPTIE] ... [BESTANDSNAAM] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Selecteer instantie om uit te voeren/beheren" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d bestand gevonden" +msgstr[1] "%d bestanden gevonden" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Fout tijdens lezen van %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Geen bestanden gevonden." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nieuwe afspeellijst" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Standaard invoer" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Audio-CD, nummer %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(tekencoderingsfout)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Stream-opname moet worden ingesteld in de Audio-instellingen voordat het kan worden gebruikt." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Fout tijdens openen van uitvoerstream" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Fout tijdens opnemen van uitvoerstream" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Fout tijdens afspelen van %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Ongeldig audioformaat" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Nu aan het afspelen" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Fout bij openen van %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Fout tijdens laden van %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Kan %s niet laden: niet-ondersteunde bestandsextensie" + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Fout tijdens opslaan van %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Kan %sniet opslaan: niet-ondersteunde bestandsextensie" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Fout bij laden van plug-in" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Spoelfout" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Bestandsformaat niet herkend" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Fout bij lezen metagegevens" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanaal" +msgstr[1] "%d kanalen" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Audio-CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Nummer %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(onbekende titel)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Onbekend URI-schema" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Ongeldige bestandsnaam" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Ongeldige toegangsmodus" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Met dank aan" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licentie" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Over Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Annuleren" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "Niet meer _vragen" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Weet je zeker dat je \"%s\" wilt verwijderen?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "Ve_rwijderen" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Afspeellijst verwijderen" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Hoe wil je deze afspeellijst noemen?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "Naam _wijzigen" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Afspeellijstnaam wijzigen" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Kies een te exporteren voorinstelling." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Voorinstellingsbestand ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF-bestand ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importeren" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exporteren" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Equalizer-voorinstellingen" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Voorinstelling opslaan" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Selectie verwijderen" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Wijzigingen terugdraaien" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "Inschak_elen" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Equalizer" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Voorinstellingen ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Terugzetten naar nul" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Voorversterker" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Bestanden openen" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Openen" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "_Venster sluiten bij openen" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Bestanden toevoegen" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Toevoegen" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "_Venster sluiten bij toevoegen" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Sluiten" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Titel" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artiest" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Genre" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Jaar" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Nummer" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Duur" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formaat:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Kwaliteit:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bitsnelheid:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Kamermuziek" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klassiek" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hardrock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop " + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock-and-Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm-and-Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Succesvol opgeslagen" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Fout tijdens opslaan" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Nummerinformatie" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Albumartiest" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Opmerking" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Titelnummer" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "Blanco velden _automatisch invullen" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "Op_slaan" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Vorige" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "Volge_nde" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "n/b" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Spoelen" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Spoelen naar tijd" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Voer tijd in (minuten:seconden):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_In wachtrij" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "_Uit wachtrij" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Ga naar nummer" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filter: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filter:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "S_luiten bij spoelen" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Overschrijven" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Overschrijven bevestigen" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "%s overschrijven?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Voer een bestandsextensie in of selecteer een formaat uit de keuzelijst." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Formaat selecteren per extensie" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Afspeellijst exporteren" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exporteren" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Afspeellijst importeren" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importeren" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Plug-ins ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Over %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Instellingen" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "In_stellen" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "In_stellingen" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Over" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Kies bestand" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Kies map" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Uiterlijk" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Geluid" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Netwerk" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Afspeellijst" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Plug-ins" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Geavanceerd" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Algemeen" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Effect" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualisatie " + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Invoer" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transport" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Albumartiest" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Titelnummer" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Bestandsnaam" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Bestandspad" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Datum" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Omschrijving" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Codec" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Kwaliteit" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Geen" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arabisch" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltisch" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Chinees" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Grieks" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebreeuws" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japans" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Koreaans" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Pools" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Russisch" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanees" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turks" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automatisch" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Zwevende komma" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Zoals gedecodeerd" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Na het toepassen van normaliseren" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Na het toepassen van effecten" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Na het toepassen van equalization" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Op basis van willekeurig" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Uiterlijk:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Uitvoerplug-in:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Alle bestanden versterken:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Bestanden zonder label versterken:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Uitvoerinstellingen" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bitdiepte:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Bufferomvang:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Zacht afknippen" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Software-volumeregelaar gebruiken (niet aanbevolen)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Opname-instellingen" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Stream opnemen:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "Normaliseren" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Normaliseren inschakelen" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Modus:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Afknippen voorkomen (aanbevolen)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Proxy-hostnaam:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Proxy-poort:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Proxy-gebruikersnaam:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Proxy-wachtwoord:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Netwerkinstellingen" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Proxy-configuratie" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Proxy gebruiken" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Authenticatie gebruiken voor proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "SOCKS-proxy gebruiken" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automatische karaktercodering-detector ingeschakeld voor:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Terugvallen op karaktercoderingen:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Gedrag" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Afspelen hervatten bij opstarten" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pauzeren in plaats van onmiddellijk hervatten" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Doorgaan zodra het huidige nummer verwijderd is" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Afspeellijst wissen bij openen van bestanden" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Bestanden openen in een tijdelijke afspeellijst" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Nummerweergave" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Titelnummers tonen" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Voorloopnullen tonen (02:00 i.p.v. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Uren gescheiden tonen (1:30:00 i.p.v. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exporteren" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Relatieve paden gebruiken (indien mogelijk)" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Albumhoes" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Zoeken naar afbeeldingen die overeenkomen met deze woorden (kommagescheiden):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Afbeeldingen negeren die overeenkomen met deze woorden (kommagescheiden): " + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Zoeken naar afbeeldingen die overeenkomen met de bestandsnaam" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Recursief zoeken" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Zoekdiepte:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Pop-upinformatie" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Pop-upinformatie tonen" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Pop-upvertraging (tienden van een seconde):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Tijdschaal tonen voor huidige nummer" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Compatibiliteit" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "\\ (achterwaartse schuine streep) interpreteren als begrenzingsteken voor een map" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Afspeellijst" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Mappen recursief toevoegen" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Mappen in afspeellijstbestanden toevoegen" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metagegevens" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Ontbrekende metagegevens herleiden uit bestandspad" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Geen metagegevens laden voordat nummers worden afgespeeld" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Inhoud onderzoeken van bestanden met niet-erkende bestandsextensie" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Overig" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Vooruit-/Terugspoelen met:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "seconden" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Volume aanpassen met:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "procent" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TITEL" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TITEL - ARTIEST" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TITEL - ARTIEST - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTIEST - TITEL" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTIEST - ALBUM -TITEL" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTIEST - ALBUM - NUMMER. TITEL" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTIEST [ ALBUM ] - NUMMER. TITEL" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - TITEL" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Categorie" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Aangepast" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Titelopmaak:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Aangepast:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Audiostream-opname inschakelen met behulp van %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Geen plug-in beschikbaar voor audio-opname" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious-instellingen" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Annuleren" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Opslaan" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Laden" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Voorinstellingsbestand laden" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "EQF-bestand laden" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Voorinstellingsbestand opslaan" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "EQF-bestand opslaan" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Wachtrijbeheer" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Uit wachtrij" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Bezig met werken..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Fout" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Informatie" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "Op_slaan naar geschiedenis" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "URL openen" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "URL toevoegen" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "_Geschiedenis wissen" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Voer een URL in:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Openen" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Verdere berichten zijn verborgen.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Voorinstellingsbestanden (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Sluiten" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Blader" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Map openen" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Map toevoegen" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Toevoegen" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Lettertype instellen" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metagegevens" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Componist" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Uitgevoerd door" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Opnamejaar" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Opnamedatum" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Technisch" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bitsnelheid" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "MusicBrainz-id" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "He_rstellen" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Fout tijdens wegschrijven van tag(s)." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 bestanden geselecteerd" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "%1 bestanden op_slaan" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Niveau" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Functie" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Bericht" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Logboek-inspecteur" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Foutopsporing" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Informatie" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Waarschuwing" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Wi_ssen" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Logniveau:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Diensten" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopiëren" diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 0000000..b8641ff --- /dev/null +++ b/po/pl.po @@ -0,0 +1,1525 @@ +# Polish translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Chris <259095+transifex@gmail.com>, 2012 +# a b, 2016 +# Bartosz Kosiorek , 2003 +# Chris <259095+transifex@gmail.com>, 2012 +# Chris <259095+transifex@gmail.com>, 2012 +# felikstayson , 2012 +# felikstayson , 2012 +# GNOME PL Team , 2004 +# Grzegorz Kowal , 2000-2001 +# mkkot , 2013 +# Marco Oliver Grunwald , 2013 +# Marco Oliver Grunwald , 2013 +# Marco Oliver Grunwald , 2013 +# mkkot , 2013-2014 +# No Ne, 2020 +# No Ne, 2018,2020 +# Piotr Sokół , 2012 +# Piotr Strębski , 2017 +# Piotr Strębski , 2014-2016 +# Szymon Weihs , 2011 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-03-27 19:54+0000\n" +"Last-Translator: No Ne\n" +"Language-Team: Polish (http://www.transifex.com/audacious/audacious/language/pl/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Wyświetl pomoc linii poleceń" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Pokaż informacje o wersji" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Rozpocznij odtwarzanie" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Wstrzymaj odtwarzanie" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Wstrzymaj i wznów odtwarzanie bieżącej ścieżki" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Zatrzymaj odtwarzanie" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Przejdź do poprzedniej piosenki" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Przejdź do następnej piosenki" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Dodaj pliki do listy odtwarzania" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Dodaj pliki do tymczasowej listy odtwarzania" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Wyświetl główne okno programu" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Wyświetla okno przejścia do piosenki" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Uruchom bez interfejsu graficznego" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Zamknij program po zakończeniu odtwarzania" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Pokaż komunikaty o błędach (może być dwukrotnie użyte)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Uruchom w trybie GTK" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Nieznana opcja: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Nieznana opcja: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Obsługa: audacious [OPCJE] ... [PLIK] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Wybierz instancję do włączenia/kontroli" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Znaleziono plik %d" +msgstr[1] "Znaleziono %d pliki" +msgstr[2] "Znaleziono %d plików" +msgstr[3] "Znaleziono %d plików" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Błąd odczytu %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Nie znaleziono plików." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nowa lista odtwarzania" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Wejście standardowe" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Płyta Audio CD, ścieżka %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(błąd dekodowania znaków)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Nagrywanie strumieniowe - przed użyciem - musi być wpierw skonfigurowane w Ustawieniach dźwięku." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Błąd otwierania strumienia wyjściowego" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Błąd nagrywania strumienia wyjściowego" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Błąd odtwarzania %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Nieprawidłowy format dźwięku" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Teraz odtwarzane" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Błąd otwierania %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Błąd wczytywania %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Nie można wczytać %s: nieobsługiwane rozszerzenie pliku." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Błąd zapisywania %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Nie można zapisać %s: nieobsługiwane rozszerzenie pliku." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Błąd wczytywania wtyczki" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Błąd wyszukiwania" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Nie rozpoznano formatu pliku" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Błąd odczytu metadanych" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanał" +msgstr[1] "%d kanały" +msgstr[2] "%d kanałów" +msgstr[3] "%d kanałów" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Audio CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Ścieżka %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(nieznany tytuł)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Nieznany protokół URL" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Błędna nazwa pliku" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Nieprawidłowy tryb dostępu" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Zasługi" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licencja" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Informacje o programie Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Anuluj" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Nie pytaj więcej" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Czy chcesz trwale usunąć “%s”?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Usuń" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Usuń listę odtwarzania" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Podaj nazwę listy odtwarzania" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Zmień nazwę" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Zmień nazwę listy odtwarzania" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Wybierz jedno ustawienie do wyeksportowania." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Plik ustawień..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Plik EQF..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importuj" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Eksportuj" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Ustawienia korektora" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Zapisz ustawienia" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Usuń zaznaczone" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Wycofaj zmiany" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Włącz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Korektor graficzny" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Profile ustawień..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Wyzeruj" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Przedwzmacniacz" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Otwórz pliki" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Otwórz" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Z_amknij okno po otwarciu" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Dodaj pliki" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Dodaj" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Za_mknij okno po dodaniu" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Zamknij" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Tytuł" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Wykonawca" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Gatunek" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Rok wydania" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Ścieżka" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Długość" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Format:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Jakość:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Przepływność bitowa:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Muzyka kameralna" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klasyczna" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Lekka muzyka" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Muzyka chrześcijańska" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock & Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Zapisano pomyślnie" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Błąd zapisu" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Informacje o piosence" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Wykonawca albumu" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Komentarz" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Numer ścieżki" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "_Automatycznie wypełnij puste pola" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Zapisz" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Poprzednie" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Następne" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "Nie dotyczy" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Przejdź" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Przejdź do momentu" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Wprowadź czas (min:sek):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "D_odaj do kolejki" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "U_suń z kolejki" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Przejdź do piosenki" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtr: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtr:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Zamknij przy zmianie _nagrania" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "N_adpisz" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Potwierdź nadpisanie" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Nadpisać %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Proszę wpisać rozszerzenie nazwy pliku lub wybrać format z rozwijanej listy." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Wybierz format na podstawie rozszerzenia" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Eksportuj listę odtwarzania" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Eksportuj" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importuj listę odtwarzania" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importuj" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Wtyczki..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Informacje o %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Ustawienia %s" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "U_staw" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Ustawienia" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Informacje" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Wybierz plik" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Wybierz katalog" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Wygląd" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Dźwięk" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Sieć" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Lista odtwarzania" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Wtyczki" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Zaawansowane" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Ogólne" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efekty" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Wizualizacja" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Wejście" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transport" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Wykonawca albumu" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Numer ścieżki" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nazwa pliku" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Położenie pliku" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Data wydania" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Opis" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Kodek" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Jakość" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Brak" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arabski" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Bałtycki" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Chiński" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Grecki" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebrajski" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japoński" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Koreański" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polski" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Rosyjski" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Tajwański" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turecki" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automatyczna" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Typ zmiennopozycyjny" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Zdekodowane jako" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Po zastosowaniu wyrównania głośności" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Po zastosowaniu efektów" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Po zastosowaniu korektora" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Na podstawie losowania" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interfejs:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "System dźwięku:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Wzmocnij wszystkie pliki:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Wzmocnij pliki bez etykiet:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Wyjście dźwięku" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Rozdzielczość bitowa:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Rozmiar bufora:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Usuń przesterowania w nagraniach" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Użyj programowej regulacji głośności (niezalecane)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Ustawienia nagrywania" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Strumień nagrania:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "Wyrównywanie głośności" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Włącz wyrównywanie głośności" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Tryb:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Zapobiegaj przesterowaniu (zalecane)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Nazwa serwera:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Port serwera:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Użytkownik:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Hasło:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Ustawienia sieciowe" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Konfiguracja serwera pośredniczącego" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Użyj serwera pośredniczącego" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Uwierzytelnianie" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Użyj proxy SOCKS" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automatycznie wykryj kodowania dla:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Zapasowe kodowanie znaków:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Zachowanie" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Wznów odtwarzanie przy starcie" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Wstrzymaj zamiast natychmiastowego wznowienia" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Przejdź do następnej, gdy usunę odtwarzaną piosenkę" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Czyść listę odtwarzania podczas otwierania nowych plików" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Dodaj pliki do tymczasowej listy odtwarzania" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Wyświetlanie piosenki" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Pokaż numery piosenek" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Pokaż zero początkowe (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Wydziel godziny (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Eksport" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Używaj ścieżek względnych, jeśli to możliwe" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Okładka albumu" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Wyszukaj obrazy pasujące do tych słów (oddzielone przecinkiem):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Wyklucz obrazy pasujące do tych słów (oddzielone przecinkiem):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Wyszukaj obrazy pasujące do nazwy pliku piosenki" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Wyszukaj rekurencyjnie" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Głębokość wyszukiwania:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Wyskakujące komunikaty" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Pokaż wyskakujące informacje" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Opóźnij wyskakujące komunikaty (dziesiąte sekundy):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Pokaż skalę czasową dla bieżącej piosenki" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Zgodność" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpretuj \\ (ukośnik wsteczny) jako separator folderów" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Lista odtwarzania" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Dodaj foldery rekursywnie" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Dodaj foldery zagnieżdżone w plikach listy odtwarzania" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadane" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Odgadnij brakujące metadane ze ścieżki pliku" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Opóźnij wczytywanie metadanych piosenek do czasu odtworzenia" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Wykryj zawartość plików bez rozpoznanego rozszerzenia nazwy pliku" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Różne" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Krok do przodu/do tyłu o:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "sekundy" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Dostosuj głośność o:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "procent" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TYTUŁ" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TYTUŁ - WYKONAWCA" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TYTUŁ - WYKONAWCA - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "WYKONAWCA - TYTUŁ" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "WYKONAWCA - ALBUM - TYTUŁ" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "WYKONAWCA - ALBUM - NUMER ŚCIEŻKI. TYTUŁ" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "WYKONAWCA [ ALBUM ] - NUMER ŚCIEŻKI. TYTUŁ" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - TYTUŁ" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategoria" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Własny" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Format tytułu:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Własny tekst:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Włącz nagrywanie strumienia dźwięku poprzez %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Brak dostępnej wtyczki nagrywania dźwięku" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Ustawienia Audaciousa" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Anuluj" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Zapisz" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Wczytaj" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Wczytaj plik ustawień" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Wczytaj plik EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Zapisz plik ustawień" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Zapisz plik EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Menedżer kolejki" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Usuń z kolejki" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Działanie..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Błąd" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Informacje" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Zapisz w historii" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Otwórz adres URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Dodaj adres URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "W_yczyść historię" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Wprowadź URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Otwórz" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Dalsze komunikaty zostały ukryte.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Pliki ustawień (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Zamknij" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Przeglądaj" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Otwórz katalog" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Dodaj katalog" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Dodaj" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Ustaw czcionkę" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadane" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Kompozytor" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Wykonawca" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Rok nagrania" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Data nagrania" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Techniczne" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Tempo bitowe" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "Identyfikator MusicBrainz" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Odwróć" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Błąd zapisywania tagów." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 zaznaczonych plików" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "_Zapisz %1 plików" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Poziom" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Funkcja" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Wiadomość" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Dziennik programu" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Debugowanie" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Informacje" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Ostrzeżenie" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "W_yczyść" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Poziom dziennika:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Usługi" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopiuj" diff --git a/po/process-transifex-po b/po/process-transifex-po new file mode 100755 index 0000000..0c00073 --- /dev/null +++ b/po/process-transifex-po @@ -0,0 +1,166 @@ +#!/bin/sh + +case "$1" in +ar.po) + LANGUAGE="Arabic" + ;; +ast.po) + LANGUAGE="Asturian" + ;; +be.po) + LANGUAGE="Belarusian" + ;; +bg.po) + LANGUAGE="Bulgarian" + ;; +ca.po) + LANGUAGE="Catalan" + ;; +cmn.po) + LANGUAGE="Chinese (Mandarin)" + ;; +cs.po) + LANGUAGE="Czech" + ;; +da.po) + LANGUAGE="Danish" + ;; +de.po) + LANGUAGE="German" + ;; +el.po) + LANGUAGE="Greek" + ;; +en_GB.po) + LANGUAGE="English (United Kingdom)" + ;; +eo.po) + LANGUAGE="Esperanto" + ;; +es_AR.po) + LANGUAGE="Spanish (Argentinian)" + ;; +es_MX.po) + LANGUAGE="Spanish (Mexican)" + ;; +es.po) + LANGUAGE="Spanish" + ;; +et.po) + LANGUAGE="Estonian" + ;; +eu.po) + LANGUAGE="Basque" + ;; +fa_IR.po) + LANGUAGE="Persian (Iran)" + ;; +fi.po) + LANGUAGE="Finnish" + ;; +fr.po) + LANGUAGE="French" + ;; +gl.po) + LANGUAGE="Galician" + ;; +he.po) + LANGUAGE="Hebrew" + ;; +hu.po) + LANGUAGE="Hungarian" + ;; +id_ID.po) + LANGUAGE="Indonesian" + ;; +it.po) + LANGUAGE="Italian" + ;; +ja.po) + LANGUAGE="Japanese" + ;; +ko.po) + LANGUAGE="Korean" + ;; +ky.po) + LANGUAGE="Kirgyz" + ;; +lt.po) + LANGUAGE="Lithuanian" + ;; +lv.po) + LANGUAGE="Latvian" + ;; +ml_IN.po) + LANGUAGE="Malayalam (India)" + ;; +ms.po) + LANGUAGE="Malay" + ;; +nl.po) + LANGUAGE="Dutch" + ;; +pl.po) + LANGUAGE="Polish" + ;; +pt_BR.po) + LANGUAGE="Portuguese (Brazil)" + ;; +pt_PT.po) + LANGUAGE="Portuguese" + ;; +ro.po) + LANGUAGE="Romanian" + ;; +ru.po) + LANGUAGE="Russian" + ;; +si.po) + LANGUAGE="Sinhala" + ;; +sk.po) + LANGUAGE="Slovak" + ;; +sq.po) + LANGUAGE="Albanian" + ;; +sr@latin.po) + LANGUAGE="Serbian (Latin)" + ;; +sr.po) + LANGUAGE="Serbian" + ;; +sr_RS.po) + LANGUAGE="Serbian (Serbia)" + ;; +sv.po) + LANGUAGE="Swedish" + ;; +ta.po) + LANGUAGE="Tamil" + ;; +tr.po) + LANGUAGE="Turkish" + ;; +uk.po) + LANGUAGE="Ukrainian" + ;; +vi.po) + LANGUAGE="Vietnamese" + ;; +zh_CN.po) + LANGUAGE="Chinese (simplified)" + ;; +zh_TW.po) + LANGUAGE="Chinese (traditional)" + ;; +*) + echo "Unknown language $1" + exit 1 + ;; +esac + +sed -i -e "s/SOME DESCRIPTIVE TITLE./$LANGUAGE translation for Audacious/" "$1" +sed -i -e "s/YEAR THE PACKAGE'S COPYRIGHT HOLDER/Audacious translators/" "$1" +sed -i -e "s/as the PACKAGE package/as the Audacious package/" "$1" +sed -i -e "s/LANGUAGE /$LANGUAGE/" "$1" diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 0000000..e0f9f29 --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,1528 @@ +# Portuguese (Brazil) translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Alexandro Casanova , 2012-2014 +# Bruno Lima , 2018 +# Cleber de Souza Corrêa , 2014 +# Cleiton Lima , 2011 +# Cleiton Lima , 2011 +# Cleiton Lima , 2011 +# edu engler , 2012 +# F Marcelo O Amarante , 2015 +# Fúlvio Alves , 2020 +# Habner Costa , 2013 +# Habner Costa , 2013 +# Iuri Suzano , 2017 +# jimmiemacedo , 2012 +# jimmiemacedo , 2012 +# Jorgebadad , 2016 +# Juliano da Silva Silva , 2019 +# Karen Eliot , 2011 +# Rafael Fontenelle , 2012 +# rafael garcia , 2017 +# Rodrigo de Araujo , 2016 +# Rodrigo de Araujo , 2016 +# Rodrigo de Almeida Sottomaior Macedo , 2012 +# Rui , 2018 +# Alexandro Casanova , 2012-2013 +# Alexandro Casanova , 2012 +# vitorgatti , 2012 +# vitorgatti , 2012 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-05-01 16:16+0000\n" +"Last-Translator: Fúlvio Alves \n" +"Language-Team: Portuguese (Brazil) (http://www.transifex.com/audacious/audacious/language/pt_BR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pt_BR\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Mostrar ajuda de linha de comando" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Mostrar versão" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Começar reprodução" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pausar reprodução" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pausar ou reproduzir" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Parar reprodução" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Pular para a música anterior" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Pular para a próxima música" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Adicionar arquivo(s) à lista de reprodução" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Adicionar arquivos para uma lista de reprodução temporária" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Mostrar janela principal" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Exibir a janela ir-para-a-música" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Começar sem interface gráfica" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Sair ao parar a reprodução" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Imprimir mensagens de depuração (pode ser usado duas vezes)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Executar no modo GTK" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Opção desconhecida: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Opção desconhecida: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Uso: audacious [OPCÃO] ... [ARQUIVO] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Selecione a instância para executar/controlar" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d arquivo encontrado" +msgstr[1] "%d arquivos encontrados" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Erro de leitura %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Nenhum arquivo encontrado." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nova Lista de Reprodução" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Entrada padrão" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "CD de Áudio, faixa %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(erro de codificação de caracteres)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "O fluxo de captura deve ser configurado nas Configurações De Áudio antes de ser usado" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Erro ao abrir o fluxo de saída" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Erro ao gravar fluxo de saída" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Erro ao tocar %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Formato de áudio inválido " + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Reproduzindo" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Erro ao abrir %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Erro ao carregar %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Não foi possível carregar %s: extensão do nome do arquivo não suportado." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Erro ao salvar %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Não foi possível salvar %s: extensão do nome do arquivo não suportado." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Erro ao carregar plugin" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Erro de busca" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Formato de arquivo não reconhecido" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Erro ao ler metadados" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Estéreo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d canal" +msgstr[1] "%d canais" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "CD de Áudio" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Faixa %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(título desconhecido)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Esquema de URI desconhecido" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Nome do arquivo inválido" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Modo de acesso inválido" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Créditos" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licença" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Sobre o Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Cancelar" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Não perguntar novamente" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Você quer remover “%s” permanentemente?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Remover" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Remover lista de reprodução" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Como você gostaria de chamar esta lista de reprodução?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Renomear" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Renomear Lista de Reprodução" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Selecione uma predefinição para exportar." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Arquivo de Predefinições ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Arquivo EQF ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importar" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Predefinições do Equalizador" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Salvar Predefinições" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Excluir Selecionado" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Desfazer Alterações" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Ativar" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Equalizador" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Predefinições ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Redefinir como zero" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Preamplificação" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Abrir Arquivo(s)" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Abrir" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Fechar _diálogo ao abrir" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Adicionar Arquivo(s)" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Adicionar" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Fechar _diálogo ao adicionar" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Fechar" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Título" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artista" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Álbum" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Gênero" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Ano" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Faixa" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Duração" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formato:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Qualidade:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bitrate:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambiente" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Chamber Music" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Clássica" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Salvo com sucesso" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Erro ao salvar" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Informações da Faixa" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Artista do Álbum" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Comentário" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Número da faixa" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "_Auto-preencher espaços vazios" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Salvar" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Anterior" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Próxima" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/A" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Pular" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Avançar Tempo até" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Digite o tempo (minutos:segundos):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Inserir na fila" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "_Remover da fila" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Ir para a Música" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtro:" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtro:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "F_echar ao saltar" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Sobrescrever" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Confirmar Sobrescrever" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Substituir %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Por favor, digite uma extensão de nome de arquivo ou selecione um formato a partir da lista suspensa." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Selecionar Formato por Extensão" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Exportar Lista de Reprodução" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exportar" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importar Lista de Reprodução" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importar" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Plugins ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Sobre %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Ajustes" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Definir" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Configurações" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Sobre" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Escolha arquivo" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Escolha a pasta" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Aparência" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Áudio" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Rede" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Lista de Reprodução" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Plugins" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Avançado" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Geral" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efeito" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualização" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Entrada" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transportar" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Artista do Álbum" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Número da faixa" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nome do arquivo" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Diretório do arquivo" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Data" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Descrição" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Codec" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Qualidade" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Nenhum" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Árabe" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Báltico" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Chinês" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Grego" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebraico" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japonês" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Coreano" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polonês" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Russo" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanês" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turco" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automático" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Ponto flutuante" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Como decodificado" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Após a aplicação de Ganho de Repetição" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Após a aplicação de efeitos" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Após a aplicação de equalização" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Baseado em embaralhar" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interface:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Plugin de saída:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Amplificar todos os arquivos:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Amplificar arquivos não marcados:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Configuração de Saída" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Profundidade de bit:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Tamanho do armazenamento:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Recorte suave" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Usar controle de volume de software (não recomendado)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Configurações de Gravação" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Fluxo de Registro" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "Ganho de Repetição" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Habilitar Ganho de Repetição" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Modo:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Evitar distorção (recomendado)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Proxy hostname:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Porta:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Nome de usuário proxy:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Senha do proxy:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Ajustes de Rede" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Configurações de Proxy" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Ativar o uso de proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Usar autenticação do proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Usar proxy SOCKS" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Converter caracteres automaticamente para:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Códigos de caracteres de arquivos:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Comportamento" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Retomar lista de reprodução ao iniciar" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pausar em vez de retomar imediatamente" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Avançar quando a música atual for excluída" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Limpar lista de reprodução ao abrir arquivo(s)" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Abrir arquivo(s) em uma lista de reprodução temporária" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Exibição do Arquivo" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Mostrar números das músicas" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Mostrar zeros à esquerda (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Mostrar horas separadamente (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Use caminhos relativos quando possível" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Imagem do Álbum" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Pesquisar imagens destas palavras (separado por vírgula):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Excluir imagens destas palavras (separado por vírgula):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Pesquisar imagens correspondentes ao nome do arquivo da música" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Pesquisar recursivamente" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Pesquisar profundidade:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Informações Pop-up" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Mostrar informações pop-up" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Atraso do pop-up (décimos de segundo):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Mostrar escala de tempo para a música atual" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Compatibilidade" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpretar o carácter \\ (barra invertida) como um indicador de nível na árvore de diretórios" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Lista de Reprodução" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Adicionar pastas recursivamente" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Adicionar pastas à lista de reprodução" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Detalhes" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Acho que falta metadados do caminho de arquivo" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Não carregar metadados para as músicas até que sejam tocadas" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Examinar conteúdo de arquivos sem extensão de nome de arquivo reconhecido" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Diversos" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Avançar/retroceder por:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "segundos" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Ajustar volume em:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "por cento" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TÍTULO" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TÍTULO - ARTISTA" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TÍTULO - ARTISTA - ÁLBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTISTA - TÍTULO" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTISTA - ÁLBUM - TÍTULO" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTISTA - ÁLBUM - FAIXA. TÍTULO" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTISTA [ ÁLBUM ] - FAIXA. TÍTULO" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ÁLBUM - TÍTULO" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Categoria" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Personalizado" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Formato do título:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Formato personalizado:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Habilitar fluxo de áudio com %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Nenhum plugin de gravação de áudio diponível" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Ajustes do Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Cancelar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Salvar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Carregar" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Carregar Arquivo de Predefinições" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Carregar Arquivo EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Salvar Arquivo de Predefinições" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Salvar Arquivo EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Gerenciador de Fila" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Retirar da fila" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Trabalhando ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Erro" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Informação " + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Adicionar ao histórico" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Abrir URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Adicionar URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "_Limpar histórico" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Digite a URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Abrir" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Demais mensagens foram escondidas.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Arquivos de predefinição (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Fechar" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Explorar" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Abrir Pasta" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Adicionar Pasta" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Adicionar" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Definir fonte" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadados" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Compositor" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Artista" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Ano de Gravação" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Data de Gravação" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Técnico" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bitrate" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "ID do MusicBrainz" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Reverter" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Erro ao gravar marcador(es)." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 arquivos selecionados" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "_Salvar %1 arquivos" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Nível" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Função" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Mensagem" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Registro inspetor" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Depuração" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Informações" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Aviso" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Lim_po" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Nível de Registro:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Serviços" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Copiar" diff --git a/po/pt_PT.po b/po/pt_PT.po new file mode 100644 index 0000000..1c3e80f --- /dev/null +++ b/po/pt_PT.po @@ -0,0 +1,1509 @@ +# Portuguese translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Alexandro Casanova , 2012 +# Pitxyoki , 2010 +# Pitxyoki , 2010 +# Rui , 2018 +# Alexandro Casanova , 2012 +# Sérgio Marques , 2012-2018 +# Alexandro Casanova , 2012 +# Valter Vicente , 2011 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Sérgio Marques \n" +"Language-Team: Portuguese (Portugal) (http://www.transifex.com/audacious/audacious/language/pt_PT/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pt_PT\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Mostrar ajuda da linha de comandos" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Mostrar versão" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Iniciar reprodução" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pausar reprodução" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pausar se em reprodução. Caso contrário, reproduzir." + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Parar reprodução" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Ir para a faixa anterior" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Ir para a próxima faixa" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Adicionar ficheiros à lista de reprodução" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Adicionar ficheiros a uma lista de reprodução temporária" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Mostrar janela principal" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Mostrar janela Ir para a faixa" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Iniciar sem interface gráfica" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Sair ao parar a reprodução" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Imprimir mensagens de depuração (pode ser usado duas vezes)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Opção desconhecida: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Opção desconhecida: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Utilização: audacious [OPÇÃO] ... [FICHEIRO] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Selecione a instância a executar/controlar" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d ficheiro encontrado." +msgstr[1] "%d ficheiros encontrados." + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Erro na leitura de %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Não existem ficheiros." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nova lista de reprodução" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Entrada padrão" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "CD áudio, faixa %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(erro de codificação de caracteres)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Tem que configurar a gravação do fluxo nas definições para a poder utilizar." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Erro ao abrir o fluxo de saída" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Erro ao gravar o fluxo de saída" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Erro ao reproduzir %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Formato áudio inválido" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "A reproduzir" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Erro ao abrir %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Erro ao carregar %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Não foi possível carregar %s: extensão de ficheiro não suportada." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Não foi possível guardar %s: extensão não suportada." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Erro ao carregar suplemento" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Erro de procura" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Formato de ficheiro não reconhecido" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Erro ao ler meta-dados" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Estéreo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d canal" +msgstr[1] "%d canais" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "CD áudio" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Faixa %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(título desconhecido)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Esquema URI desconhecido" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Nome de ficheiro inválido" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Modo de acesso inválido" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Créditos" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licença" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Sobre o Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Cancelar" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Não perguntar novamente" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Pretende eliminar \"%s\" permanentemente?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Remover" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Remover lista de reprodução" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Gostaria de invocar esta lista de reprodução?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "Muda_r nome" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Mudar nome da lista de reprodução" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Ficheiro de pré-ajuste..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Ficheiro EQF..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importar" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Pré-ajuste de equalizador" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Guardar pré-ajuste" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Eliminar seleção" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Reverter alterações" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Ativar" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Equalizador" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Pré-ajuste..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Repor para zero" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Amplificador" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Abrir ficheiros" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Abrir" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Fechar _diálogo ao abrir" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Adicionar ficheiros" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Adicionar" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Fechar _diálogo ao Adicionar" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "Fe_char" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Título" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artista" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Álbum" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Género" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Ano" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Faixa" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Duração" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formato:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Qualidade:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Taxa de dados:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambiente" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Música de câmara" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Clássica" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Música ligeira" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Guardado com sucesso" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Erro ao guardar" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Informações da faixa" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Artista do álbum" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Comentário" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Número da faixa" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Guardar" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "Segui_nte" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/D" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Ir para faixa" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Ir para posição temporal" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Indique o tempo (minutos:segundos):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Colocar na fila" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "_Retirar da fila" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Ir para a faixa" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filtro: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filtro:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Fec_har ao ir para a faixa" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Substituir" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Confirmação de substituição" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Substituir %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Por favor digite uma extensão de ficheiro ou selecione um formato na lista." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Selecionar formato por extensão" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Exportar lista de reprodução" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exportar" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importar lista de reprodução" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importar" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "E_xtras..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Sobre o %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Definições de %s" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Definir" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "Definiçõe_s" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "S_obre" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Escolher ficheiro" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Escolher pasta" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Aparência" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Áudio" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Rede" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Lista de reprodução" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Extras" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Avançado" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Geral" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efeitos" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualizações" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Reprodução" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transporte" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Artista do álbum" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Número da faixa" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Nome de ficheiro" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Caminho de ficheiro" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Data" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Codificador" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Qualidade" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Nenhum" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Árabe" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Báltico" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Mandarim" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Grego" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebraico" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japonês" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Coreano" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polaco" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Russo" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanês" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turco" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automático" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Vírgula flutuante" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Conforme descodificado" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Após aplicação de ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Depois de aplicar os efeitos" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Depois de aplicar o equalizador" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Baseado na mistura" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Interface:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Suplemento de som:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Amplificar todos os ficheiros:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Amplificar ficheiros sem \"tags\":" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Definições de som" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Profundidade:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Memória:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Distorção suave" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Utilizar controlo de volume do programa (não recomendado)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Definições de gravação" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Fluxo de gravação:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Ativar ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Modo:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Prevenir distorção (recomendado)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Nome do proxy:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Porta do proxy:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Nome de utilizador do proxy:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Palavra-passe do proxy:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Definições de rede" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Configuração do proxy" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Ativar utilização do proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Utilizar autenticação do proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Deteção automática da codificação de caracteres para:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Codificação alternativa de caracteres:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Comportamento" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Retomar reprodução ao iniciar" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pausa em vez de retomar imediatamente" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Avançar ao eliminar a faixa atual" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Limpar lista de reprodução ao abrir ficheiros" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Abrir ficheiros numa lista de reprodução temporária" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Exibição de faixas" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Mostrar número da faixa" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Mostrar zeros iniciais (02:00 vs 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Mostrar horas separadamente (1:30:00 vs 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exportar" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Se possível, utilizar caminhos relativos" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Imagem do álbum" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Procurar imagens que tenham estas palavras (separadas por vírgula):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Excluir imagens que tenham estas palavras (separadas por vírgula):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Procurar imagens concidentes com o nome do ficheiro" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Procurar recursivamente" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Extensão da procura:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Alertas de informação" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Mostrar alertas" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Atraso do alerta (décimas de segundo):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Mostrar escala de tempo da faixa atual" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Compatibidade" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpretar \\ (barra invertida) como delimitador de pastas" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Lista de reprodução" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Adicionar pastas recursivamente" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Adicionar pastas dentro de ficheiros de listas de reprodução" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Detalhes" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Adivinhar detalhes inexistentes com base no caminho" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Não carregar detalhes da faixa antes da reprodução" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Testar conteúdo dos ficheiros que não tenham uma extensão de ficheiro reconhecida" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Diversos" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "segundos" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "Título" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "Título - Artista" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "Título - Artista - Álbum" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "Artista - Título" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "Artista - Álbum - Título" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "Artista - Álbum - Faixa. Título" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "Artista [Álbum] - Faixa. Título" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "Álbum - Título" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Categoria" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Personalizado" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Formato do título:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Linha personalizada:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Ativar gravação do fluxo áudio com %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Não está disponível um suplemento de gravação" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Definições do Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Cancelar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Guardar" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Carregar" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Carregar ficheiro de pré-ajuste" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Carregar ficheiro EQF" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Guardar ficheiro de pré-ajuste" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Guardar ficheiro EQF" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Gestão de fila de reprodução" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Remover da fila" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Execução..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Erro" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Informações" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "Guardar no hi_stórico" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Abrir URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Adicionar URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "_Limpar histórico" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Indique o URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Abrir" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Foram ocultas algumas mensagens.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Fechar" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Procurar" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Abrir pasta" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Adicionar pasta" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Adicionar" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Detalhes" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Compositor" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Intérprete" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Ano de gravação" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Data de gravação" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Técnico" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Taxa de dados" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Nível" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Função" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Mensagem" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Inspetor de registos" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Depuração" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Info" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Aviso" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "_Limpar" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Nível de registo:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Serviços" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Copiar" diff --git a/po/ru.po b/po/ru.po new file mode 100644 index 0000000..bf2c1eb --- /dev/null +++ b/po/ru.po @@ -0,0 +1,1543 @@ +# Russian translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Alexander Orlov , 2007 +# Денис , 2014 +# michurin , 2011 +# Andrei Stepanov, 2014,2016 +# Andrei Stepanov , 2014,2016 +# Ilyas B Arinov , 2014 +# Danila E , 2018 +# 85f5ad14c5f803c69d22f4aeb4ef6a7e, 2018 +# Dmitriy Glian , 2014 +# Someonefree , 2014 +# Eugene Paskevich , 2010,2015-2016 +# Eugene Zagidullin , 2007 +# Ilyas B Arinov , 2014 +# iavojd , 2013 +# iavojd , 2013 +# Ilyas B Arinov , 2014,2016 +# Oleg , 2012 +# Lowrider , 2014 +# Max Musatov , 2012 +# Max Musatov , 2012 +# michurin , 2011 +# Mikhail Zavarzin , 2018 +# Max Musatov , 2012 +# NaiLi (aka jamesjames) Rootaerc , 2012 +# NaiLi (aka jamesjames) Rootaerc , 2012 +# Oleg , 2012 +# Lowrider , 2014-2015 +# Rax Garfield , 2012 +# Rax Garfield , 2012 +# serg0 , 2009 +# serg0 , 2010 +# serg0 , 2010 +# Someonefree , 2014 +# Oleg , 2012 +# Vitaly Lipatov , 2007 +# Виктор Голованенко , 2020 +# Денис , 2014-2015 +# Денис Локтев , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-04-18 06:48+0000\n" +"Last-Translator: Виктор Голованенко \n" +"Language-Team: Russian (http://www.transifex.com/audacious/audacious/language/ru/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ru\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Показать помощь по командной строке" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Показать версию" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Начать воспроизведение" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Приостановить воспроизведение" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Приостановить при проигрывании, иначе ― воспроизводить" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Остановить воспроизведение" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Перейти к предыдущей песне" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Перейти к следующей песне" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Добавить файлы в список воспроизведения" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Добавить файлы во временный список воспроизведения" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Показать главное окно" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Показать окно переключения песен" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Запуск без графического интерфейса" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Выйти по окончании воспроизведения" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Выводить отладочные сообщения (может использоваться дважды)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Запустить в режиме GTK" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Неизвестная опция: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Неизвестная опция: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Использование: audacious [Опция] ... [Файл] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Выбрать экземпляр для запуска/управления" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Найден %d файл" +msgstr[1] "Найдено %d файла" +msgstr[2] "Найдено %d файлов" +msgstr[3] "Найдено %d файлов" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Ошибка чтения %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Файлы не найдены." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Новый список воспроизведения" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Стандартный ввод" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Аудио CD, дорожка %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(ошибка кодировки)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Прежде, чем использовать запись потока, её нужно настроить в разделе \"Звук\"." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Ошибка открытия потока вывода" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Ошибка: запись в поток вывода невозможна" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Ошибка воспроизведения %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Недопустимый звуковой формат" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Сейчас воспроизводится" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Ошибка открытия %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Ошибка загрузки %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Невозможно загрузить %s: расширение файла не поддерживается." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Ошибка сохранения %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Невозможно сохранить %s: расширение файла не поддерживается." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Ошибка загрузки модуля" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Ошибка перемотки" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Неопознанный формат файла" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Ошибка чтения метаданных" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Моно" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Стерео" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d канал" +msgstr[1] "%d канала" +msgstr[2] "%d каналов" +msgstr[3] "%d каналов" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Аудио CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Дорожка %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(неизвестное название)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Неизвестная схема URI" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Недопустимое имя файла" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Недопустимый режим доступа" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Авторы" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Лицензия" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Об Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Отмена" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Не спрашивать снова" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Вы хотите удалить “%s” без возможности восстановления?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Удалить" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Удалить список воспроизведения" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Как вы хотите назвать этот список воспроизведения?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Переименовать" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Переименовать список воспроизведения" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Файл предустановок ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Файл предустановок эквалайзера ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Импорт" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Экспорт" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Предустановки эквалайзера" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Сохранить предустановки" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Удалить выбранное" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Откатить изменения" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Включить" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Гц" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 кГц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 кГц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 кГц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 кГц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 кГц" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Эквалайзер" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Предустановки ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Сбросить на ноль" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Предусиление" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Открыть файлы" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Открыть" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Закрыть _диалог при открытии" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Добавить файлы" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Добавить" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Закрыть _диалог при добавлении" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Закрыть" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Название" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Исполнитель" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Альбом" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Жанр" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Год" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Дорожка" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Продолжительность" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Формат:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Качество:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Битрейт:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Chamber Music" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Classical" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Easy Listening" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Успешно сохранено" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Ошибка сохранения" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Информация о песне" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Исполнитель альбома" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Комментарий" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Номер дорожки" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Сохранить" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "С_ледующая" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d кб/с" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "нет данных" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Перейти" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Перейти ко времени" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Введите время (минуты:секунды):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "Поставить в _очередь" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Удалить из _очереди" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Перейти к композиции" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Фильтр: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Фильтр:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "За_крыть после перехода" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Перезаписать" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Подтвердить перезапись" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Перезаписать %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Введите расширение файла или выберите формат из выпадающего списка." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Выберите формат расширения" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Экспортировать список воспроизведения" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Экспортировать" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Импортировать список воспроизведения" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Импортировать" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Модули ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "О %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Настройки %s" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Установить" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Настройки" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Описание" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Выберите файл" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Выберите каталог" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Внешний вид" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Звук" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Сеть" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Список воспроизведения" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Модули" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Продвинутые" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Общие" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Эффект" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Визуализация" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Ввод" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Транспорт" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Исполнитель альбома" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Номер дорожки" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Имя файла" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Расположение файла" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Дата" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Описание" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Кодек" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Качество" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Нет" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Арабский" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Балтийские языки" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Китайский" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Греческий" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Иврит" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Японский" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Корейский" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Польский" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Русский" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Тайваньский" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Турецкий" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Автоматически" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Плавающая точка" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "После раскодирования" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "После выравнивания громкости" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "После применения эффектов" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "После применения эквалайзера" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Основано на воспроизведении в произвольном порядке" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Интерфейс:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Модуль вывода:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Усилить звук во всех файлах на:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "дБ" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Усилить звук в файлах без меток на:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Настройки вывода" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Разрядность выходного потока:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Размер буфера:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "мс" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Мягкое отсечение" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Использовать программную регулировку громкости (не рекомендуется)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Настройки записи" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Запись потока:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "Выравнивание громкости" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Включить выравнивание громкости" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Режим:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Предотвратить отсечение (рекомендуется)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Имя узла прокси-сервера:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Порт:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Имя пользователя:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Пароль:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Сетевые настройки" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "КиБ" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Настройка прокси-сервера" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Использовать прокси" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Использовать авторизацию с прокси" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Использовать SOCKS-прокси" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Автоматически определять кодировку для языка:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Если не удалось определить, использовать кодировку:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Поведение" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Продолжить воспроизведение при запуске" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Пауза вместо немедленного продолжения" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Продвигаться дальше, если текущая композиция удалена" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Очистить список воспроизведения при открытии файлов" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Открывать файлы во временном списке воспроизведения" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Отображение композиций" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Показывать номер композиции" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Показывать нули в начале (02:00 вместо 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Показывать часы отдельно (1:30:00 вместо 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Экспорт" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Используйте относительные пути, если это возможно" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Обложка альбома" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Искать изображения, содержащие эти слова (разделять запятыми):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Исключать изображения, содержащие эти слова (разделять запятыми):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Искать изображения, совпадающие с композицией по имени файла" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Рекурсивный поиск" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Глубина поиска:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Всплывающее информационное окно" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Показывать всплывающее информационное окно" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Задержка всплывания (десятые доли секунды):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Показывать шкалу времени для текущей композиции" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Совместимость" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Считать \\ (обратную косую черту) разделителем имён каталогов" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Список воспроизведения" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Добавлять каталоги рекурсивно" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Добавлять каталоги, содержащиеся в списках воспроизведения" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Метаданные" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Определять отсутствующие метаданные по пути файла" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Не загружать метаданные композиций до воспроизведения" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Воспроизводить файлы с неизвестными расширениями" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Разное" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "секунд" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "НАЗВАНИЕ" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "НАЗВАНИЕ - ИСПОЛНИТЕЛЬ" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "НАЗВАНИЕ - ИСПОЛНИТЕЛЬ - АЛЬБОМ" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ИСПОЛНИТЕЛЬ - НАЗВАНИЕ" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ИСПОЛНИТЕЛЬ - АЛЬБОМ - НАЗВАНИЕ" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ИСПОЛНИТЕЛЬ - АЛЬБОМ - ДОРОЖКА. НАЗВАНИЕ" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ИСПОЛНИТЕЛЬ [ АЛЬБОМ ] - ДОРОЖКА. НАЗВАНИЕ" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "АЛЬБОМ - НАЗВАНИЕ" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Категория" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Другой формат" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Формат названия:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Задать формат:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Включить запись звукового потока с помощью %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Нет доступных модулей для записи звука" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Настройки Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Отмена" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Сохранить" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Загрузить" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Загрузить файл предустановок" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Загрузить файл предустановок эквалайзера" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Сохранить файл предустановок" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Сохранить файл предустановок эквалайзера" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Управление очередью" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Убрать из очереди" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Работаю ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Ошибка" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Информация" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "Сохранить в историю" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Открыть веб-ссылку" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Добавить веб-ссылку" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "О_чистить историю" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Введите веб-ссылку:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Открыть" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Подробные сообщения были скрыты.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Закрыть" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Обзор" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Открыть каталог" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Добавить каталог" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Добавить" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Метаданные" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Композитор" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Исполнитель" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Год записи" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Дата записи" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Технические" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Битрейт" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Ошибка записи тэга(ов)." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Уровень" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Функция" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Сообщение" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Инспектор журнала" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Отладка" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Информация" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Предупреждение" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Чи_сто" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Уровень журналирования:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Службы" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Копировать" diff --git a/po/si.po b/po/si.po new file mode 100644 index 0000000..5c16805 --- /dev/null +++ b/po/si.po @@ -0,0 +1,1505 @@ +# Sinhala translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Ashintha Rukmal Perera , 2013 +# Ashintha Rukmal Perera , 2013 +# Deenuka Niroshini Perera , 2013 +# Deenuka Niroshini Perera , 2013 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Ashintha Rukmal Perera \n" +"Language-Team: Sinhala (http://www.transifex.com/audacious/audacious/language/si/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: si\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "අනුවාදය පෙන්නන්න " + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "අනුවාදය​ පෙන්නන්න​" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "ගොනු ධාවන ලැයිස්තුවට එකතු කරන්න " + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "ප්‍රධාන කවුළුව සංදර්ශනය කරන්න​" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr " \t \tපසුබිම් ගායනයෙන් නික්මෙන්න" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "ඔඩේෂස්" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d ගොනුව හමුවිය " +msgstr[1] "%d ගොනු හමුවිය " + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "" + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "නව ධාවන ලැයිස්තුව" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "\tශ්‍රව්‍ය CD, පථ %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "දැන් ධාවනයවේ" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "තනි " + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "ත‍්‍ර‍්‍රිමාණ " + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d නාලිකාව" +msgstr[1] "%d නාලිකා " + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "ශ්‍රව්‍ය CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "\tසම්මානය" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "වරපත " + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "ඔඩේෂස් පිළිබඳ " + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_අවලංගු කරන්න​" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_නැවත නම්කිරීම " + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "ධාවන ලැයිස්තුව නැවත නම්කරනවා " + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "ආයාත කරන්න " + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "\t_සබල කරනවා" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "සමානකරණය" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "" + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "පූර්ව වර්ධකය " + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "ගොනු විවෘත කරන්න" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "ගොනු එකතු කරන්න" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_වසන්න​" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "මාතෘකාව" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "ශිල්පියා " + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "ඇල්බමය " + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "ප්‍රභේදය" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "වර්ෂය " + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "ඛණ්ඩය " + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "දිග" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "හැඩතලය​:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "ප්‍රශස්තතාව:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "කටුක ඝෝෂාකර සංගීතය" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "ඇසිඩ් රොක් " + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "හාත්පස පැතිරුණු" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "ජෑස් සංගීතය " + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "බ්ලුග්‍රාස් " + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "බ්ලූස් " + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "ශාලිකා සංගීතය" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "සම්භාව්‍ය" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "දේශය " + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr " ඩෙත් මෙට්ල් " + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "ඩිස්කෝ නැටුම " + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "පහසු ඇහුන්කන් දීම " + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "ජන සමූහය " + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "බියගුල්ලා " + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "ගැනස්ටර් රැප් " + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "අනුශාසනය " + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "හාඩ් රොක්" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "හෙවි මෙට්ල් " + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "හිප්-පොප්" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "නිවස " + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "ජෑස්" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "කැලෑව" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "ලෝහය" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "නව යුගය" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "\tනව තරංගය" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "ඝෝෂාව" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "ජනප‍්‍රිය " + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "පන්ක් රොක් " + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "තට්ටු කරනවා" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "රෙගේයී සංගීතය" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "පැද්දෙනවා " + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "රොක් ඇන්ඩ් රෝල් " + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr " \tරිද්මය සහ බ්ලු සංගීතය" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "ස්කා " + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "ආත්මය " + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "පැද්දීම " + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "තාක්ෂණික" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "ට්‍රිප්-හොප්" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "ගීත තොරතුරු " + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "විවරණය" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_ඊළඟ​" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "මගහැර වේලාවට පිවිසෙන්න" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "ඇතුලත් කරන කාළය (මිනිත්තු:තත්පර):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "\t_පේළිය" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Un_පේළිය" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "මගහැර ගීතයට පිවිසෙන්න " + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "\tපෙරහන:" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_පෙරහන:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "\tඋඩින් ලිවීම %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "ධාවන ලැයිස්තුව නිර්යාත කරන්න" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr " ධාවන ලැයිස්තුව ආයාත කරන්න" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "" + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "%s පිළිබඳ " + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s හි සිටුවම් " + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "ෆෝල්ඩරය තෝරන්න " + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "ශ්‍රව්‍ය​" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "ජාලය" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "ධාවන ලැයිස්තුව​" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "පේනු මෘදුකාංගය" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "සාමාන්‍ය" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "ප‍්‍රතිඑලය" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "දෘෂ්‍යකරණය" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "ආදානය" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "\tප‍්‍රවාහණය" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "ගොනු නම​" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "ගොනු පථය" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "දිනය " + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "කොඩෙක් " + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "\tප්‍රශස්තතාව" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "කිසිසේත් නැති" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "අරාබි භාෂාව" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "බෝල්ටික්" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "චීන" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "ග්‍රීක" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "\tහීබෲ" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "ජපන් " + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "කොරියානු" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "ඔපකරය" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "රුසියානු" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "තායිවානීය " + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "තුර්කීය " + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "ඉපිලෙන ලක්ෂ්‍යය" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr " \tප්‍රතිදාන පේනු මෘදුකාංගය " + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "සියලු ගොනු විස්තාරණය කිරීම " + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr " නොඇමුණු ගොනු විස්තාරණය කිරීම " + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "\tප්‍රතිදාන සිටුවම් " + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr " බිටු ගැඹුර" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "බෆරයේ ප්‍රමාණය " + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "\tමෘදුකාංග පරිමා පාලකය භාවිතා කරන්න නිර්දේශ කරනොමැත" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "මෘදු ඇමිණීම" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "මෘදුකාංග පරිමා පාලකය භාවිතා කරන්න (නිර්දේශ කරනොමැත)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "ඇමුණුම වළක්වන්න (නිර්දේශිතයි)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "නියුතු සත්කාරක නාමය:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "නියුතු තොට:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "නියුතු පරිශීලක නාමය: " + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "\tනියුතු මුරපදය:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "නියුතු වින්‍යාසය" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "නියුතු භාවිතය සබල කිරිම" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "නියුතු සමඟ සත්‍යාපනය භාවිතා කරන්න" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "ස්වයංක්‍රීය අනුලකුණු කේතන අනාවරකය:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "පිහිටාධාර අනුලකුණු කේතන:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "\tචර්යාව" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "\tප්‍රවර්තන ගීතය මැකුනු පසු ප්‍රගමනයවේ " + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "ගොනු විවෘත වන විට ධාවන ලැයිස්තුව හිස් කරන්න " + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "ගොනු තාවකාලික ධාවන ලැයිස්තුවක විවෘත කරන්න " + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "ගීත සංදර්ශකය" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "ගීත අංක පෙන්නන්න" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "ඇල්බම් කලාව" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "මෙම වචන වලට ගැලපෙන අනුරූ සීහුම් කිරීම (විරාම වෙන්කරන ලද):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "මෙම වචන වලට ගැලපෙන අනුරූ ඉවත් කිරීම (comma-separated):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "ගීත ගොනුවේ නාමයට ගැලපෙන අනුරූ සෙවීම " + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "සමාවර්තව සෙවීම " + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "\tගැඹුරට සෙවීම:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "උත්පතන තොරතුරු " + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "උත්පතන තොරතුරු පෙන්නන්න " + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "උත්පතන ප්‍රමාදය (තත්පරයෙන් දහයෙන් පංගුවකි):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "දැන් පවත්නා ගීතයේ කාල පරිමාව පෙන්නන්න " + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "ගැළපුම " + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "අර්ථනිරූපණය කරන්න \\ (පසු ඇල ඉර) ෆෝල්ඩර පරිසීමකයක් ලෙස " + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "පාරදත්ත" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "ධාවනය වනතුරු ගීත සඳහා පාර-දත්ත ප්‍රවේශනය නොකරන්න " + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "විවිධ" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "තප්පර​" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "මාතෘකාව" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "\tකලාකරු - මාතෘකාව" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "කලාකරු - ඇල්බමය - මාතෘකාව" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "කලාකරු - ඇල්බමය - ඛණ්ඩය. මාතෘකාව" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "කලාකරු [ ඇල්බමය ] - ඛණ්ඩය. මාතෘකාව" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ඇල්බමය - මාතෘකාව" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "\tප්‍රවර්ගය" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "අභිරුචිය " + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "මාතෘකා ආකෘතිය:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "අභිරුචි අනුලකුණු වැල:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "අවලංගු කිරීම​" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "සුරකින්න " + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "ප්‍රවේශනය " + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "\tපේළි කළමනාකරණය " + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "" + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "දෝෂය " + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "URL විවෘත කරන්න" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "URL එකතු කරන්න" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "\tURL ඇතුල් කරන්න:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(අතිරේක පණිවිඩ සඟවන ලඳි.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "පිරික්සන්න​" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "බිට් රේටය​" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "පිටපත් කරන්න " diff --git a/po/sk.po b/po/sk.po new file mode 100644 index 0000000..2fef0c3 --- /dev/null +++ b/po/sk.po @@ -0,0 +1,1517 @@ +# Slovak translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Andrej Časo , 2017 +# Andrej Herceg , 2007,2009-2011 +# Lukáš Dobránsky , 2012-2013 +# Corduroy , 2013 +# filipbielik , 2014 +# filipbielik , 2014 +# Lukáš Dobránsky , 2012 +# Lukáš Dobránsky , 2012-2013 +# RichiSk , 2015 +# Tomáš Tomovčík , 2016 +# Tomáš Vadina , 2012 +# Corduroy , 2013 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: John Lindgren \n" +"Language-Team: Slovak (http://www.transifex.com/audacious/audacious/language/sk/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sk\n" +"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Zobraziť pomocníka k príkazovému riadku" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Zobrazí verziu" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Prehrať" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pozastaviť" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pri prehrávaní pozastaví, inak začne prehrávať" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Zastaviť" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Predchádzajúca pieseň" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Nasledujúca skladba" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Pridá súbory do zoznamu skladieb" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Pridať súbory do dočasného zoznamu skladieb" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Zobrazí hlavné okno" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Zobraziť zoznam skladieb" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Spustiť bez grafického prostredia" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Ukončiť program po zastavení prehrávania" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Zobraziť ladiace hlásenia" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Neznáma možnosť: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Neznáma možnosť: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Použitie: audacious [OPTION] ... [FILE] ...\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Zvoľte miesto pre spustenie/ovládanie" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Nájdených %d súborov" +msgstr[1] "Nájdený %d súbor" +msgstr[2] "Nájdené %d súborov" +msgstr[3] "Nájdené %d súborov" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Nastala chyba pri čítaní%s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Žiadne súbory neboli nájdené." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Nový zoznam skladieb" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "štandardný vstup" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Zvukové CD, stopa %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(chyba kódovania znakov)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Nahrávanie streamu musí byť najprv nakonfigurované v Nastaveniach Zvuku, až potom bude možné nahrávať." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Chyba počas otvárania výstupného streamu" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Nastala chyba počas nahrávania výstupného streamu" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Nastala chyba počas prehrávania %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Neplatný zvukový formát" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Práve hrá" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Nastala chyba počas otvárania %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Nastala chyba počas nahrávania %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Nie je možné načítať %s: nepodporovaná prípona názvu súboru." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Nie je možné uložiť %s: nepodporovaná prípona súboru." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Nastala chyba pri nahraní zásuvného modulu" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Nastala chyba pri vyhľadávaní" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Formát súboru nebol rozpoznaný" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Nastala chyba počas načítavania metadát" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanálov" +msgstr[1] "%d kanál" +msgstr[2] "%d kanály" +msgstr[3] "%d kanály" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Zvukové CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Stopa %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(neznámy názov)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Neznáma URI schéma" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Neplatný názov súboru" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Neplatný režim prístupu" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Zásluhy" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licencia" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "O Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Zrušiť" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Už sa znovu nepýtať" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Naozaj chcete nenávratne odstrániť \"%s\"?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Odstrániť" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Odstrániť zoznam skladieb" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Ako chcete pomenovať tento zoznam skladieb?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Premenovať" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Premenovať zoznam skladieb" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Súbor s predvoľbami ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Súbor EQF ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importovať" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exportovať" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Predvoľby ekvalizéru" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Uložiť predvoľbu" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Odstrániť zvolené" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Vrátiť zmeny" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Povoliť" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Ekvalizér" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Predvoľby" + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Zresetovať na nulu " + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Predzosilnenie" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Otvoriť súbory" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Otvoriť" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Zatvoriť okno po otvorení" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Pridať súbory" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "Pridať" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Zatvoriť okno po pri_daní" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Zatvoriť" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Názov" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Umelec" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Žáner" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Rok" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Stopa" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Dĺžka" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Formát:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Kvalita:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Dátový tok:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ambient" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Komorná hudba" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klasika" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Príjemné počúvanie" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "Nová vlna" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Ruch" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Techno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Úspešne uložené." + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Nastala chyba pri ukladaní" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Info. o skladbe" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Umelec albumu" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Komentár" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Číslo stopy" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "Uložiť" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Nasledujúca" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "Nedostupné" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Preskočiť" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Prejsť na čas" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Zadajte čas (minúty:sekundy):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "Pridať do _fronty" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Odo_brať z fronty" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Prejsť na skladbu" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filter: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filter:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Zatvoriť po skoku" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Prepísať" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Prepísať" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Prepísať %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Prosím zadajte príponu súboru alebo vyberte formát zo zoznamu." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Zvoľte formát podľa prípony" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Exportovať zoznam skladieb" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exportovať" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importovať zoznam skladieb" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importovať" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "Zásuvné mo_duly ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "O %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Nastavenia" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Nastaviť" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Nastavenia" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "O _programe" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Zvoliť súbor" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Vybrať priečinok" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Vzhľad" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Zvuk" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Sieť" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Zoznam skladieb" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Zásuvné Moduly" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Všeobecné" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efekt" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Vizualizácia" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Vstup" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Prenos" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Umelec albumu" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Číslo stopy" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Názov súboru" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Cesta k súboru" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Dátum" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Kodér" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Kvalita" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Žiadne" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arabčina" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltské jazyky" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Čínština" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Gréčtina" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebrejčina" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japončina" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Kórejčina" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Poľština" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Ruština" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwančina" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turečtina" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automatický" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Plávajúca desatinná čiarka" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Dekódované" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Po aplikovaní ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Po aplikovaní efektov" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Po aplikovaní ekvalizácie" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Na základe náhodnosti" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Prostredie:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Výstupný modul:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Zosilniť všetky súbory:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Zosilniť súbory bez popisov:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Nastavenia výstupu" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bitová hĺbka:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Veľkosť vyrovnávacej pamäte:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Jemné orezanie" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Použiť softvérové ovládanie hlasitosti (neodporúča sa)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Nastavenie nahrávania" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Nahrať stream:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Povoliť ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Režim:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Predchádzať orezávaniu (odporúča sa)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Meno počítača:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Port:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Používateľ:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Heslo:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Nastavenia pripojenia" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Nastavenie proxy" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Používať proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Používať autentifikáciu" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automatické rozoznávanie kódovania znakov:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Záložné kódovanie znakov:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Správanie" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Po spustení pokračovať v prehrávaní" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Ihneď pozastaviť namiesto pokračovania" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Prejsť na nasledujúcu skladbu, ak je aktuálna skladba odstránená" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Pri otvorení súborov vyprázdniť zoznam skladieb" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Otvoriť súbory do dočasného zoznamu skladieb" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Zobrazenie skladby" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Zobraziť čísla skladieb" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Zobraziť úvodnú nulu (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Zobraziť hodiny oddelene (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Album" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Vyhľadať obrázky odpovedajúce týmto slovám (oddelené čiarkou):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Vylúčiť obrázky odpovedajúce týmto slovám (oddelené čiarkou):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Hľadať obrázky odpovedajúce názvu súboru" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Hľadať rekurzivne" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Hĺbka hľadania:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Vyskakovacie okno s podrobnosťami" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Zobraziť okno s informáciami" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Oneskorenie vyskakovania (desatiny sekundy):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Zobraziť časový merač pre aktuálnu skladbu" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Kompatibilita" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Interpret \\ (spätné lomítko) ako oddeľovač priečinku" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadáta" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Uhádnuť chýbajúce metadáta z cesty súboru" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Nenačítať metadáta skladieb pred prehraním" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Preskúmať obsah súborov, pri ktorých nieje známa prípona" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Rôzne" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "sekúnd" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "NÁZOV" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "NÁZOV - UMELEC" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "NÁZOV - UMELEC - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "UMELEC - NÁZOV" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "UMELEC - ALBUM - NÁZOV" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "UMELEC - ALBUM - STOPA. NÁZOV" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "UMELEC [ALBUM] - STOPA. NÁZOV" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - NÁZOV" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategória" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Vlastné" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Formát názvu:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Vlastný reťazec:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Povoliť nahrávanie audio streamu s pomocou %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Nieje dostupný žiadny zásuvný modul pre nahrávanie audia" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Nastavenia programu" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Zrušiť" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Uložiť" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Nahrať" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Načítať predvoľby" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Načítať EQF súbor" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Uložiť súbor s predvoľbami" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Uložiť EQF súbor" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Správca fronty" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Vyradiť z fronty" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Pracujem..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Chyba" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Informácie" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Otvoriť URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Pridať URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Zadajte URL:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Otvoriť" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Ďalšie správy boli skryté.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Zatvoriť" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Prechádzať" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Otvoriť priečinok" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Pridať priečinok" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Pridať" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadáta" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Skladateľ" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Účinkujúci" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Rok nahrávania" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Dátum nahrávania" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Technický" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Dátový tok" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Úroveň" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Funkcia" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Správa" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Inšpektor logov" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Ladenie" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Informácie" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Upozornenie" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Vy_mazať" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Úroveň logu:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Služby" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopírovať" diff --git a/po/sr.po b/po/sr.po new file mode 100644 index 0000000..5c4386d --- /dev/null +++ b/po/sr.po @@ -0,0 +1,1507 @@ +# Serbian translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Мирослав Николић , 2013 +# Strahinja Kustudic , 2007-2008 +# Мирослав Николић , 2011-2014 +# Мирослав Николић , 2013 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Мирослав Николић \n" +"Language-Team: Serbian (http://www.transifex.com/audacious/audacious/language/sr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sr\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Приказује помоћ линије наредби" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Приказује издање" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Започиње пуштање" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Паузира пуштање" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Паузира ако свира, иначе пушта" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Зауставља пуштање" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Иде на претходну песму" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Иде на следећу песму" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Додаје датотеке на списак нумера" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Додаје датотеке на привремени списак нумера" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Приказује главни прозор" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Приказује прозор за бирање песама" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Покреће се без графичког сучеља" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Излази на заустављање пуштања" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Исписује поруке прочишћавања (може бити коришћено два пута)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Непозната опција: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Непозната опција: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Употреба: audacious [ОПЦИЈА] ... [ДАТОТЕКА] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Изаберите примерак за покретање/управљање" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Аудацијус" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Пронашао сам %d датотеку" +msgstr[1] "Пронашао сам %d датотеке" +msgstr[2] "Пронашао сам %d датотека" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Грешка читања „%s“:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Нисам нашао ниједну датотеку." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Нови списак нумера" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Стандардни улаз" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Звучни ЦД, нумера %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(грешка кодирања знакова)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Грешка отварања излазног тока" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Грешка пуштања „%s“:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Неисправан запис звука" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Сад пуштам" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Грешка отварања „%s“:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Грешка учитавања „%s“." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Не могу да учитам „%s“: проширење назива датотеке није подржано." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Не могу да сачувам „%s“: проширење назива датотеке није подржано." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Грешка учитавања прикључка" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Грешка премотавања" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Запис датотеке није познат" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Грешка читања метаподатака" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Моно" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Стерео" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d канал" +msgstr[1] "%d канала" +msgstr[2] "%d канала" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Звучни ЦД" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Нумера %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(непознат наслов)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Непозната шема путање" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Неисправан назив датотеке" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Неисправан режим приступа" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Заслуге" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Дозвола" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "O Аудацијусу" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Откажи" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Не питај поново" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Да ли желите да трајно уклоните „%s“?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Уклони" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Уклони списак нумера" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Како желите да назовете овај списак нумера?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Преименуј" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Преименуј списак нумера" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Датотека претподешавања ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "ЕКуФ датотека ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Увези" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Извези" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Претподешавања уједначавача" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Сачувај претподешавање" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Обриши изабрано" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Поврати измене" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Укључи" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Уједначавач" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Претподешавања ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Врати на нулу" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Претпојачање" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Отвори датотеке" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Отвори" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Затвори _прозорче на „Отвори“" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Додај датотеке" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Додај" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Затвори _прозорче на „Додај“" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Затвори" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Наслов" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Извођач" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Албум" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Жанр" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Година" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Нумера" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Дужина" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Запис:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Квалитет:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Проток бита:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Кисели џез" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Кисели рок" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Амбијентална" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Бебоп" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Блуграс" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Блуз" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Камерна музика" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Класична" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Кантри" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Мртви метал" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Диско" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Лако слушање" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Народна" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Фанки" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Гангста реп" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Верска" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Гранџ" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Хард рок" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Хеви метал" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Хип-Хоп" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "Хауз" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Џез" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Џунгла" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Метал" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "Ново доба" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "Нови талас" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Бука" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Поп" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Панк Рок" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Реп" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Реге" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Рок" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Рокенрол" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Ритам и Блуз" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ска" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Соул" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Свинг" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Техно" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Трип-Хоп" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Чување је успело" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Чување није успело" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Подаци песме" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Извођач албума" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Напомена" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Број нумере" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Сачувај" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Следеће" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "Н/Д" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Скочи" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Пређи на време" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Унесите време (минути:секунде):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Стави у ред" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "_Избаци из реда" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Пређи на песму" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Филтер: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Издвој:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Затвори после _скока" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Препиши" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Потврди преписивање" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Да препишем „%s“?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Упишите проширење назива датотеке или изаберите запис са падајућег списка." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Изаберите запис према проширењу" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Извези списак нумера" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Извези" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Увези списак нумера" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Увези" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Прикључци ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "О програму „%s“" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Подешавања %sа" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Подеси" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Подешавања" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_О програму" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Изаберите датотеку" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Изаберите фасциклу" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Изглед" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Звук" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Мрежа" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Списак нумера" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Прикључци" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Опште" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Дејство" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Приказивање" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Унос" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Пренос" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Извођач албума" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Број нумере" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Назив датотеке" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Путања датотеке" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Датум" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Кодек" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Квалитет" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Ништа" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "арапски" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "балтички" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "кинески" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "грчки" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "јеврејски" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "јапански" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "корејски" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "пољски" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "руски" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "тајвански" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "турски" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Аутоматски" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Покретни зарез" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Као декодер" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Након примене појачања понављања" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Након примене дејстава" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Након примене изједначавања" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Прикључак излаза:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Појачај све датотеке:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Појачај датотеке без ознака:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Подешавања излаза" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Дубина бита:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Величина међумеморије:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Меко исецање" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Користи софтверско управљање јачином звука (није препоручљиво)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Подешавања снимања" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Сними ток:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "Појачање понављања" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Укључује појачање понављања" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Спречи одсецање (препоручљиво)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Назив домаћина посредника:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Прикључник посредника:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Корисничко име посредника:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Лозинка посредника:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Подешавања мреже" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Подешавања посредника" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Укључи коришћење посредника" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Користи потврђивање идентитета са посредником" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Самостални откривач кодирања знакова за:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Резервна кодирања знакова:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Понашање" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Настави пуштање при покретању" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Застани уместо да наставиш одмах" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Напредуј када је обрисана текућа песма" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Очисти списак нумера приликом отварања датотека" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Отвори датотеке у привременом списку нумера" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Приказ песме" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Прикажи бројеве песама" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Прикажи почетне нуле (02:00 уместо 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Прикажи часове издвојено (1:30:00 уместо 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Омот албума" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Потражи слике које одговарају овим речима (раздвојене зарезом):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Искључи слике које одговарају овим речима (раздвојене зарезом):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Потражи слике које одговарају називу песме" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Потражи дубински" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Дубина претраге:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Облачић података" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Прикажи облачиће података" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Застој искакања (десетинке секунде):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Прикажи временску лествицу за текућу песму" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Сагласност" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Протумачи \\ (контра косу црту) као граничник фасцикле" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Метаподаци" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Погоди недостајуће метаподатке из путање датотеке" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Не учитавај метаподатке за песме док се не пусте" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Испробај садржај датотека са непознатим проширењем назива датотеке" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Разно" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "секунде" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "НАСЛОВ — ИЗВОЂАЧ" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "НАСЛОВ — ИЗВОЂАЧ — АЛБУМ" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ИЗВОЂАЧ — НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ИЗВОЂАЧ — АЛБУМ — НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ИЗВОЂАЧ — АЛБУМ — БРОЈ. НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ИЗВОЂАЧ [ АЛБУМ ] — БРОЈ. НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "АЛБУМ — НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Категорија" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Произвољно" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Запис наслова:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Произвољна ниска:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Није доступан прикључак за снимање звука" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Подешавања Аудацијуса" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Откажи" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Сачувај" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Учитај" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Учитај датотеку претподешавања" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Учитај ЕКуФ датотеку" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Сачувај датотеку претподешавања" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Сачувај ЕКуФ датотеку" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Управник реда" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Избаци из реда" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Радим ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Грeшкa" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Информације" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Отворите адресу" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Додајте адресу" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Унеси адресу:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Отвори" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Додатне поруке су скривене.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Затвори" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Отворите фасциклу" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Додајте фасциклу" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Додај" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Метаподаци" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Композитор" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Извођач" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Година снимања" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Датум снимања" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Технички" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Проток бита" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Ниво" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Функција" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Порука" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Надзорник дневника" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Прочишћавање" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Подаци" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Упозорење" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Ниво дневника:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Услуге" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Умножи" diff --git a/po/sr_RS.po b/po/sr_RS.po new file mode 100644 index 0000000..1f74eba --- /dev/null +++ b/po/sr_RS.po @@ -0,0 +1,1504 @@ +# Serbian (Serbia) translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Мирослав Николић , 2014 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Мирослав Николић \n" +"Language-Team: Serbian (Serbia) (http://www.transifex.com/audacious/audacious/language/sr_RS/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sr_RS\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Приказује помоћ линије наредби" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Приказује издање" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Започиње пуштање" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Паузира пуштање" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Паузира ако свира, иначе пушта" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Зауставља пуштање" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Иде на претходну песму" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Иде на следећу песму" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Додаје датотеке на списак нумера" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Додаје датотеке на привремени списак нумера" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Приказује главни прозор" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Приказује прозор за бирање песама" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Покреће се без графичког сучеља" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Излази на заустављање пуштања" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Непозната опција: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Непозната опција: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Употреба: audacious [ОПЦИЈА] ... [ДАТОТЕКА] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Безочник" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Пронашао сам %d датотеку" +msgstr[1] "Пронашао сам %d датотеке" +msgstr[2] "Пронашао сам %d датотека" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "" + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Нови списак нумера" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Звучни ЦД, нумера %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Сад пуштам" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Моно" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Стерео" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d канал" +msgstr[1] "%d канала" +msgstr[2] "%d канала" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Аудио ЦД" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Заслуге" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Дозвола" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "O Безочнику" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Откажи" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Не питај поново" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Да ли желите да трајно уклоните „%s“?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Уклони" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Уклони списак нумера" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Како желите да назовете овај списак нумера?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Преименуј" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Преименуј списак нумера" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Увези" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Извези" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Укључи" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Уједначавач" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "" + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Претпојачање" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Отвори датотеке" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Отвори" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Затвори _прозорче на „Отвори“" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Додај датотеке" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Додај" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Затвори _прозорче на „Додај“" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Затвори" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Наслов" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Извођач" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Албум" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Жанр" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Година" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Нумера" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Дужина" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Запис:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Квалитет:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Проток бита:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Кисели џез" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Кисели рок" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Амбијентална" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Бебоп" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Блуграс" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Блуз" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Камерна музика" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Класична" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Кантри" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Мртви метал" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Диско" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Лако слушање" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Народна" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Фанки" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Гангста реп" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Верска" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Гранџ" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Хард рок" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Хеви метал" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Хип-Хоп" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "Хауз" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Џез" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Џунгла" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Метал" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "Ново доба" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "Нови талас" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Бука" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Поп" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Панк Рок" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Реп" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Реге" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Рок" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Рокенрол" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Ритам и Блуз" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ска" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Соул" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Свинг" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Техно" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Трип-Хоп" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Чување је успело" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Чување није успело" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Подаци песме" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Напомена" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Број нумере" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Сачувај" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "С_ледеће" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "Н/Д" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Скочи" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Пређи на време" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Унесите време (минути:секунде):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "Стави у _ред" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Избаци из _реда" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Пређи на песму" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Пропусник: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Пропусти:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Затвори после _скока" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Потврди преписивање" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Да препишем „%s“?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Извези списак нумера" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Увези списак нумера" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Прикључци ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Подешавања за %s" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Подеси" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Подешавања" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_О програму" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Изаберите фасциклу" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Изглед" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Звук" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Мрежа" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Списак нумера" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Прикључци" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Опште" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Дејство" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Приказивање" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Унос" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Пренос" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Назив датотеке" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Путања датотеке" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Датум" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Кодек" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Квалитет" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Ништа" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "арапски" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "балтички" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "кинески" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "грчки" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "јеврејски" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "јапански" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "корејски" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "пољски" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "руски" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "тајвански" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "турски" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Покретни зарез" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Прикључак излаза:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Појачај све датотеке:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Појачај датотеке без ознака:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Подешавања излаза" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Дубина бита:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Величина међумеморије:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Меко исецање" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Користи софтверско управљање јачином звука (није препоручљиво)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Спречи одсецање (препоручљиво)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Назив домаћина посредника:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Прикључник посредника:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Корисничко име посредника:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Лозинка посредника:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Подешавања посредника" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Укључи коришћење посредника" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Користи потврђивање идентитета са посредником" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Самостални откривач кодирања знакова за:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Резервна кодирања знакова:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Понашање" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Напредуј када је обрисана текућа песма" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Очисти списак нумера приликом отварања датотека" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Отвори датотеке у привременом списку нумера" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Приказ песме" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Прикажи бројеве песама" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Омот албума" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Потражи слике које одговарају овим речима (раздвојене зарезом):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Искључи слике које одговарају овим речима (раздвојене зарезом):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Потражи слике које одговарају називу песме" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Потражи дубински" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Дубина претраге: " + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Облачић података" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Прикажи облачиће података" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Застој искакања (десетинке секунде):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Прикажи временску лествицу за текућу песму" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Сагласност" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Протумачи \\ (контра косу црту) као граничник фасцикле" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Метаподаци" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Не учитавај метаподатке за песме док се не пусте" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "секунде" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ИЗВОЂАЧ — НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ИЗВОЂАЧ — АЛБУМ — НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ИЗВОЂАЧ — АЛБУМ — БРОЈ. НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ИЗВОЂАЧ [ АЛБУМ ] — БРОЈ. НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "АЛБУМ — НАСЛОВ" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Категорија" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Произвољно" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Запис наслова:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Произвољна ниска:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Подешавања Безочника" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Откажи" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Сачувај" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Учитај" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Управник реда" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "Избаци из _реда" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "" + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Грeшкa" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Отворите адресу" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Додајте адресу" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Унеси адресу:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Отвори" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Додатне поруке су скривене.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Затвори" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Претражи" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Битски проток" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Упозорење" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Умножи" diff --git a/po/sv.po b/po/sv.po new file mode 100644 index 0000000..549b4e1 --- /dev/null +++ b/po/sv.po @@ -0,0 +1,1512 @@ +# Swedish translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Anders Jonsson , 2018 +# Andreas Rönnquist , 2015 +# Andreas Rönnquist , 2015 +# Bo Serrander , 2013 +# Fredrik Ismyren , 2014 +# cb445fb3dfd1fe3c2b9f58ac5638f478, 2015-2016 +# Jonatan Nyberg , 2018-2020 +# Jonatan Nyberg , 2017-2018 +# Luna Jernberg , 2015 +# Luna Jernberg , 2014 +# Martin Persenius , 2004 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-03-28 05:05+0000\n" +"Last-Translator: Jonatan Nyberg \n" +"Language-Team: Swedish (http://www.transifex.com/audacious/audacious/language/sv/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: sv\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Visa kommandoradshjälp" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Visa version" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Börja uppspelning" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Pausa uppspelning" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Pausa om spelandes, spela annars" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Stoppa uppspelning" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Hoppa till föregående låt" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Hoppa till nästa låt" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Lägg till filer i spellista" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Lägg till nya filer i temporär spellista" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Visa huvudfönstret" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Visa hoppa-till-låt-fönstret" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Starta utan ett grafiskt gränssnitt" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Avsluta vid uppspelningsstopp" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Skriv ut avlusningsmeddelanden (kan användas dubbelt)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Kör i GTK-läge" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Okänt alternativ: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Okänt alternativ: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Användning: audacious [FLAGGA] ... [FIL] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Välj instans för att köra/kontrollera" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d fil hittades" +msgstr[1] "%d filer hittades" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Fel vid läsning av %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Inga filer hittades." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Ny spellista" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Standardinmatning" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Ljud-CD, spår %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(teckenkodningsfel)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Ströminspelning måste konfigureras i ljudinställningar innan den kan användas." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Det gick inte att öppna utgångsströmmen" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Fel vid inspelning av utgångsströmmen" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Fel vid uppspelning av %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Felaktigt ljudformat" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Spelar nu" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Fel vid öppning av %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Fel vid inläsning av %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Kan inte läsa in %s: filändelsen stöds ej." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Fel vid sparande av %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Kan inte spara %s: filändelsen stöds ej." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Fel vid inläsning av insticksmodul" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Sökfel" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Okänt filformat" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Fel vid läsning av metadata" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanal" +msgstr[1] "%d kanaler" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Ljud-CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Spår %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(okänd titel)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Okänt URI-schema" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Felaktigt filnamn" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Felaktigt åtkomstläge" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Lista över medverkande" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Licens" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Om Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Avbryt" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Fråga inte igen" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Vill du radera “%s“ permanent?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Ta bort" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Ta bort spellista" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Vad vill du kalla denna spellista?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Byt namn" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Byt namn på spellista" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Välj en förinställd för att exportera." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Förinställ fil ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF-fil ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Importera" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Exportera" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Förinställningar för utjämnaren" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Spara förinställning" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Ta bort valda" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Ångra ändringar" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Aktivera" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Utjämnare" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Förinställningar ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Återställ till noll" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Förförstärkare" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Öppna filer" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Öppna" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Stäng _dialogfönstret vid öppning" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Lägg till filer" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Lägg till" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Stäng _dialogfönstret vid tilläggning" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Stäng" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Titel" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Artist" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Album" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Genre" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "År" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Spår" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Längd" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Format:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Kvalitet:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Överföringskapacitet:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Bakgrundsljud" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Kammarmusik" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klassisk" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Lättlyssnat" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folkdans" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsterrap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hårdrock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Jazz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Oljud" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punkrock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Tekno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Sparning lyckades" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Sparning misslyckades" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Låtinformation" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Albumartist" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Kommentar" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Spårnummer" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "_Fyll i tomma fält automatiskt" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Spara" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Föregående" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Nästa" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "inte tillgänglig" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Hoppa" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Hoppa till tid" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Ange tid (minuter:sekunder):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Kö" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "K_öa inte" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Hoppa till låt" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Filter: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Filter:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "S_täng vid hopp" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Skriv över" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Bekräfta överskrivning" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Skriva över %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Ange en filändelse eller välj ett format från rullgardinsmenyn." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Välj format efter filändelse" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Exportera spellista" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Exportera" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Importera spellista" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Importera" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Insticksmoduler ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Om %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s-inställningar" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Ställ in" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Inställningar" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Om" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Välj fil" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Välj mapp" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Utseende" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Ljud" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Nätverk" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Spellista" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Insticksmoduler" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Avancerat" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Allmänt" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Effekt" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Visualisering" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Inmatning" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Transportera" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Albumartist" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Spårnummer" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Filnamn" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Filsökväg" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Datum" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Beskrivning" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Kodek" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Kvalitet" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Ingen" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arabiska" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltiska" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Kinesiska" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Grekiska" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Hebreiska" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japanska" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Koreanska" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Polska" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Ryska" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Taiwanesiska" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Turkiska" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Automatisk" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Flyttal" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Som avkodad" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Efter applicering av ReplayGain" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Efter tillämpande av effekter" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Efter applicering av utjämning" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Baserat på blandning" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Gränssnitt:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Utgångsinsticksmodul:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Förstärk alla filer:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Förstärk otaggade filer:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Utgångsinställningar" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Överföringsdjup:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Buffertstorlek:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Mjuk klippning" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Använd programvaruvolymkontroll (rekommenderas inte)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Inspelningsinställningar" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Inspelningsström:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Aktivera ReplayGain" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Läge:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Förhindra klippning (rekommenderas)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Proxyvärdnamn:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Proxyport:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Proxyanvändar-ID:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Proxylösenord:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Nätverksinställningar" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Proxykonfiguration" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Använd proxy" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Använd autentisering med proxy" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Använd SOCKS-proxy" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Automatisk teckenkodningsdetektor för:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Reservteckenkodningar:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Beteende" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Fortsätt uppspelning vid start" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Pausa istället för att fortsätta direkt" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Avancera när den aktuella låten tas bort" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Rensa spellistan när du öppnar filer" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Öppna filer i en temporär spellista" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Låtvisning" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Visa låtnummer" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Visa inledande nollor (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Visa timmar separat (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Exportera" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Använd relativa sökvägar när det är möjligt" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Albumomslag" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Leta efter bilder som matchar följande ord (kommaseparerade):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Ta inte med bilder som matchar följande ord (kommaseparerade):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Sök efter bilder som matchar låttitel" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Rekursiv sökning" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Sökdjup:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Poppupp-information" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Visa poppupp-information" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Poppupp-fördröjning (tiondelar av en sekund):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Visa tidsskala för aktuell låt" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Kompatibilitet" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Tolka \\ (omvänt snedstreck) som en mappavgränsare" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Spellista" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Lägg till mappar rekursivt" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Lägg till mappar nästlade inuti spellistfiler" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadata" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Gissa saknad metadata från filsökväg" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Läs inte in låtarnas metadata innan de spelas" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Undersök innehåll i filer med okänd filändelse" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Diverse" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "sekunder" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Justera volymen med:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "procent" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "TITEL" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "TITEL - ARTIST" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "TITEL - ARTIST - ALBUM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ARTIST - TITEL" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ARTIST - ALBUM - TITEL" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ARTIST - ALBUM - SPÅR. TITEL" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ARTIST [ ALBUM ] - SPÅR. TITEL" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBUM - TITEL" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategori" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Anpassad" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Titelformat:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Anpassad sträng:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Aktivera inspelning av ljudström med %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Ingen insticksmodul för ljudinspelning tillgänglig" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious-inställningar" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Avbryt" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Spara" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Läs in" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Läs in förinställningsfil" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Läs in EQF-fil" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Spara förinställningsfil" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Spara EQF-fil" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Köhanterare" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Köa inte" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Arbetar ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Fel" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Information" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Spara i historiken" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Öppna webbadress" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Lägg till webbadress" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "R_ensa historik" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Ange webbadress:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Öppna" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Ytterligare meddelanden har dolts.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Förinställda filer (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Stäng" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Bläddra" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Öppna mapp" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Lägg till mapp" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Lägg till" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Ställ in typsnitt" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Metadata" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Kompositör" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Uppträdare" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Inspelningsår" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Inspelningsdatum" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Teknisk" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Överföringskapacitet" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "MusicBrainz-ID" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Återgå" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Fel vid skrivning av tagg(ar)." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 filer valda" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "_Spara %1 filer" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Nivå" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Funktion" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Meddelande" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Logginspekterare" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Avlusa" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Info" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Varning" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "R_ensa" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Loggnivå:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Tjänster" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopiera" diff --git a/po/ta.po b/po/ta.po new file mode 100644 index 0000000..76d5e80 --- /dev/null +++ b/po/ta.po @@ -0,0 +1,1507 @@ +# Tamil translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Sivarajah Bagerathan , 2013 +# Gobikrishnan , 2015 +# Nareshwar Raju Vaneshwar , 2013 +# Nareshwar Raju Vaneshwar , 2013 +# Sivarajah Bagerathan , 2013 +# Vanavarayan Vanthiyathevan , 2019 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: Nareshwar Raju Vaneshwar \n" +"Language-Team: Tamil (http://www.transifex.com/audacious/audacious/language/ta/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ta\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "பதிப்பை காட்டு" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "பின்னணியை தொடங்கு " + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "பின்னணியை இடை நிறுத்து " + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "பாடல் இயங்குமானால் இடைநிறுத்து, இல்லையெனில் இயங்க வை" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "பின்னணியை முற்றாக நிறுத்து " + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "முந்தைய பாட்டுக்கு செல் " + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "அடுத்த பாட்டுக்கு செல் " + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "பாடல் பட்டியலுக்கு கோப்புகளை உட்செலுத்தவும்" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "பிரதான சாளரத்தை காட்சிப்படுத்தவும்" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "பாடல் இயக்கத்தை நிறுத்தும் போது விலக்குக" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "ஔடகிவஸ்" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d கோப்பு காணப்படவில்லை" +msgstr[1] "%d கோப்புக்கள் காணப்படவில்லை" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "கோப்புகள் எதுவும் கண்டறியப்படவில்லை " + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "புதிய பாடல் பட்டியல்" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "ஒலி இறுவட்டு, பாடல், %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "தற்போது இயக்கப்படுவது" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "சொருகி" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "பிழையை தேடுங்கள்" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "தனித்த " + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "ஒலிப்பிரிப்பு" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "" +msgstr[1] "" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "ஒலி இறுவட்டு" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(அறியாத தலைப்பு)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "ஏற்க முடியாத கோப்பு பெயர் " + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "நற்பெயர்கl" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "உரிமம்" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "ஔடகிவஸ் பற்றி" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_இரத்து செய் " + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "மறுபடியும் கேட்காதே " + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "நீங்கள் நிரந்தரமாக %s ஐ நீக்கப்போக்கின்றிர்களா ?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "நீக்கு " + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "பாடல் பட்டியலை நீக்கு " + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "இந்த பாடல் பட்டியலை எவ்வாறு அழைக்க விரும்புகின்றிர்கள் ?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_மீள்பெயரிடு" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "பாடல் பட்டியலினை மறுபெயர் செய்க " + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "" + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF கோப்பு ...." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "இறக்குமதி செய்க" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "ஏற்றுமதி செய் " + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "தெரிவு செய்யப்பட்டவையை அழி " + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_செயல்படுத்தவும்" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "சமமாக்கி" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "" + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "munperukki" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "கோப்புக்களைத் திறக்கவும் " + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_திற " + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "கோப்புக்களை சேர்க்கவும் " + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_சேர் " + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_மூடவும்" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "தலைப்பு" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "பாடகர்" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "செருகேடு\n " + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "வகை" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "வருடம்" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "paadal" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "பாடலின் கால அளவிடை " + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "வடிவமைப்பு: " + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "தரம்:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bit வீதம் " + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "ஆசிட் ஜாஸ்" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "ஆசிட் ராக்" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "சுற்றுச்சூழல்" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "பெபாப்" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "ப்ளூகிராஸ்" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "ப்ளூஸ்" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "சபை இசை" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "பாரம்பரிய இசை" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "கிராமப்புறப்பாடல்கள் " + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "டெத் metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "disco" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "எளிதாக கேட்கக் கூடியவை" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "நாட்டுப்புறப் பாடல்கள்" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "நவநாகரீகமானவை" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "குழு ராப்" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "நற்செய்தி " + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "granj" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "ஹார்ட் raak" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "ஹெவி mettal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "ஹிப்-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "hawus" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "jaas" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "ஜங்கள்" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "mettal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "புதிய படிப்புகl" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "புதிய அலைகள் " + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "இரைச்சல் சத்தம் " + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "போப் " + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "பங்க் raak" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "ராப் " + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "rage" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "ராக் " + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "ராக் மற்றும் ரோல் " + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "ரிதம் மற்றும் blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "skaa" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "உயிர் " + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "tekno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "ட்ரிப்-ஹாப் " + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "சேமிப்பு வெற்றிகரமானது " + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "பாடல் விபரம்" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "செருகேடு கலைஞர் " + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "கருத்து " + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "சுவட்டு எண் " + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_சேமி " + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_அடுத்து " + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "நேரத்திற்கு செல்லவும் " + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "நேரத்தை பதிவு செய்க (நிமிடங்கள்:வினாடிகள்)" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_வரிசை" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "வரிசைகளை நீக்கு" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "பாடலுக்கு தாவுக" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "வடிகட்டுக" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_வடிகட்டுக:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_மேல் எழுது " + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "மேல் எழுதுதலை உறுதிப்படுத்து " + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "%s மேலெழுதுக ?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "பாடல் பட்டியலை ஏற்றுமதி செய்க " + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_ஏற்றுமதி " + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "பாடல் பட்டியலை இறக்குமதி செய்க " + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "இறக்குமதி " + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "" + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "%s பற்றி" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s அமைப்புகள்" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_அமை " + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_அமைப்பு " + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_பற்றி " + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "கோப்பை தெரிவு செய் " + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "கோப்பகமொன்றை தேர்க " + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "தோற்றம் " + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "ஒலி" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "வலையமைப்பு" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "பாடல் பட்டியல்" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "நீட்சிகள்" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "மேம்பட்ட " + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "பொதுவானது" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "விளைவுகள் " + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "உருவக காட்சிப்படுத்தல் " + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "உள்ளீடு " + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "போக்குவரத்து" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "செருகேடு கலைஞர் \n " + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "சுவட்டு எண் " + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "கோப்பின் பெயர் " + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "கோப்பு வழி " + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "திகதி" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "குறியாக்கி / விலக்கி" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "தரம்" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "எதுவும் அல்ல " + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "அரபிக்" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "பால்ரிக்" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "சீனம்" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "கிரேக்கம்" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "ஹீபுரு" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "ஜப்பானீஸ்" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "கொரியன்" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "பொலிஸ்" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "உருசியன்" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "தாய்வானீஸ்" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "துருக்கி" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "தன்னியக்கம் " + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "மிதவை புள்ளி" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "குலுக்குதலை அடிப்படையாக கொண்டது " + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "இடைமுகம் " + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "வெளியீட்டு நீட்சிகள்" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "அனைத்து கோப்புகளினதும் சப்தத்தை பெருக்கு:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "இணைக்கப்படாத கோப்புகளின் சப்தத்தை பெருக்கு:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "வெளியீட்டு அமைப்புகl" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bit ஆழம்" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "தாங்கல் அளவு" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "மென்மையான துண்டாக்கல் " + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "மென்பொருள் ஒலி கட்டுப்படுத்தியை உபயோகிக்க (பரிந்துரைக்கப்பட்ட முறைமை அல்ல)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "பதிவுசெய்தல் அமைப்பு " + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "நறுக்குதலை தவிர்க்கவும் (பரிந்துரைக்கப்பட்ட முறைமை)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "பதிலி வழங்குநர் பெயர்" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "பதிலி போர்ட் எண்:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "பதிலி பயனர்பெயர்:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "பதிலி கடவுச்சொல் " + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "வலைப்பின்னல் அமைப்பு " + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB " + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "பதிலி உள்ளமைவு" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "பதிலி பயன்பாட்டினை செயல்படுத்துக" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "பதிலியுடன் உறுதிப்பாட்டினையும் பயன்படுத்துக " + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "குறியிடப்பட்ட உணர்கருவிகள் எந்த தானியங்கு எழுத்துகளுக்கு: " + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "குறைவடையும் எழுத்துகளுக்கான குறியீடுகள்:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "நடத்தை" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "தற்போதைய பாடல் நீக்கப்படும் பட்சத்தில் அடுத்த பாடலுக்கு முன்னேறு " + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "கோப்புகளை திறக்கும் போது குறித்த பாடல் பட்டியலை நீக்குக " + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "தற்காலிக பாடல் பட்டியலில் கோப்புகளை திறக்க " + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "பாடல் காட்சி " + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "பாடல் இலக்கங்களை காட்டுக " + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "மணித்தியாலங்களை தனியாக காட்டு (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "ஏற்றுமதி" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "செருகேடு வரைவு" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "இச்சொற்களுக்கு பொருத்தமான நிழற்படங்களை தேடுக (காற்புள்ளியால் பிரிக்குக):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "இச்சொற்களுக்கு பொருத்தமான நிழற்படங்களை நீக்குக (காற்புள்ளியால் பிரிக்குக):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "இப்பாடல் கோப்பு பெயருக்கு பொருத்தமான நிழற்படங்களை தேடுக" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "மீள்சுழலலாக தேடுக " + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "தேடும் ஆழம்:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "மேல்மீட்பு தகவல்" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "மேல்மீட்பு தகவல்களை காண்பிkkuga" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "மேல்மீட்பு தாமதம் (ஒரு வினாடியின் பத்து பிரிவுகளாக)" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "தற்போதைய பாடலின் கால அளவிடையை காண்பிக்க" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "இணக்கத்தன்மை " + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr " \\ (பின்னோக்கிய சாய்வு) இனை கோப்புறை எல்லையாக வரையறுக்க" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "பாடல் பட்டியல்" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "மீத்தரவு " + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "தவறிய மீதரவுகளை கோப்பு வழியில் இருந்து ஊகி " + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "பாடல்களினை இயக்கும் வரை மீத்தரவினை ஏற்ற வேண்டாம்" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "வினாடிகள் " + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "தலைப்பு " + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "தலைப்பு-கலைஞர் " + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "தலைப்பு-கலைஞர்-செருகேடு\n " + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "கலைஞர் - தலைப்பு" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "கலைஞர் - செருகேடு\n  - தலைப்பு" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "கலைஞர் - குறுவட்டு - பாடல். தலைப்பு" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "கலைஞர் [குறுவட்டு] - பாடல். தலைப்பு" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "குறுவட்டு - தலைப்பு" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "வகை " + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "தனிப்பயன்" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "தலைப்பு வடிவம்:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "தனிப்பயன் சரம்:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "ரத்து செய்க " + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "சேமிக்குக " + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "ஏற்றுக " + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "வரிசை நிர்வாகி" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "" + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "தவறுகள் " + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "தகவல் " + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_வரலாற்றில் சேமி " + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "முகவரியை திற" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "முகவரியை சேர்" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "முகவரியை உள்ளிடு:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "திற " + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "உலாவு " + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "கோப்பகத்தை திற " + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "கோப்பகத்தை சேர் " + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "சேர் " + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "மீதரவு " + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "இசையமைப்பாளர்" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "செயலாற்றுபவர் " + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "பதிவு செய்யப்பட்ட வருடம் " + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "பதிவு செய்யப்பட்ட தினம் " + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "தொழிநுட்ப ரீதியானது " + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "பிட்வீதம்" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "நிலை " + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "தொழிற்பாடு " + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "செய்தி " + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "எச்சரிக்கை " + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "சேவைகள் " + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "நகலேடுக்குக" diff --git a/po/tr.po b/po/tr.po new file mode 100644 index 0000000..0bbce15 --- /dev/null +++ b/po/tr.po @@ -0,0 +1,1530 @@ +# Turkish translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Önder Yıldırım , 2013 +# aamet , 2012 +# aamet , 2012 +# abc Def , 2020 +# Imnune , 2012 +# Ali Orhun Akkirman , 2013 +# hsngrms , 2012 +# Dragon Blogger , 2018 +# Dragon Blogger , 2016 +# Emre FIRAT , 2013 +# Emin Tufan , 2016 +# Emre FIRAT , 2013 +# hsngrms , 2012 +# Imnune , 2012 +# irem harmancı , 2013 +# irem harmancı , 2013 +# maruf1 , 2013 +# M. Tayyip Yel , 2013 +# Murat Senel , 2007 +# Murat Şenel , 2007 +# Zekeriya Cihan , 2013 +# Önder Yıldırım , 2013 +# tarkan255 , 2012 +# M. Tayyip Yel , 2013 +# tarkan255 , 2012 +# Volkan Gezer , 2014-2015 +# Yaşar Çiv , 2018 +# Yaşar Çiv , 2020 +# Zekeriya Cihan , 2013 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-04-28 08:51+0000\n" +"Last-Translator: Yaşar Çiv \n" +"Language-Team: Turkish (http://www.transifex.com/audacious/audacious/language/tr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: tr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Komut satırı yardımını göster" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Sürüm bilgisini göster" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Oynatmayı başlat" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Oynatmayı duraklat" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Duraklat veya devam et" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Oynatmayı durdur" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Önceki şarkıya geç" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Sonraki şarkıya geç" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Çalma listesine dosya ekle" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Dosyaları geçici bir listeye ekle" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Ana pencereyi göster" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Şarkıya atla penceresini görüntüle" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Grafiksel arayüz olmadan başla" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Kayıttan yürütmeyi durdur ve çık" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Hata ayıklama iletilerini yazdır (iki kez kullanılabilir)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "GTK modunda çalıştır" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Bilinmeyen seçenek: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Bilinmeyen seçenek: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Kullanım: audacious [SEÇENEK] ... [DOSYA] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Çalıştırılacak/kontrol edilecek örneği seçin" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "%d dosya bulundu" +msgstr[1] "%d dosya bulundu" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "%s okunurken hata:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Dosya bulunamadı." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Yeni Çalma Listesi" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Standart giriş" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Ses CD'si, parça %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(karakter kodlama hatası)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Akış kaydı, kullanılmadan önce Ses Ayarları'nda yapılandırılmalıdır." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Çıktı akışı açılırken hata" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Çıkış akışı kaydedilirken hata oluştu" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "%s açılırken hata:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Geçersiz ses biçimi" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Şimdi Çalınıyor" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "%s açılırken hata:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "%s yüklenirken hata." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "%s yüklenemiyor: bilinmeyen dosya uzantısı." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "%s kaydedilirken hata oluştu." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "%s kaydedilemiyor: bilinmeyen dosya uzantısı." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Eklenti yüklenirken hata" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Arama hatası" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Dosya biçimi tanınmadı" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Üst veri okunurken hata" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Mono" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Stereo" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d kanal" +msgstr[1] "%d kanal" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Ses CD'si" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Parça %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(bilinmeyen başlık)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Bilinmeyen URI şeması" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Geçersiz dosya adı" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Geçersiz erişim kipi" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Katkıda bulunanlar" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Lisans" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Audacious Hakkında" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_İptal" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Bir daha sorma" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "\"%s\" ögesini kalıcı olarak silmek istiyor musunuz?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Kaldır" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Çalma Listesini Kaldır" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Bu dosya adına ne ad vermek istersiniz?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Yeniden Adlandır" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Listeyi Yeniden Adlandır" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Lütfen dışa aktarmak için bir ön ayar seçin." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Önayar Dosyası ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF Dosyası ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "İçe aktar" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Dışa aktar" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Dengeleyici Önayarları" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Önayarı Kaydet" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Seçileni Sil" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Değişiklikleri Geri al" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Etkinleştir" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Dengeleyici" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Önayarlar ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Sıfırla" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Ön güçlendirme" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Dosyaları Aç" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Aç" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Açtıktan sonra _pencereyi kapat" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Dosyaları Ekle" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Ekle" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Ekledikten sonra _pencereyi kapat" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Kapat" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Başlık" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Sanatçı" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Albüm" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Tür" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Yıl" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Parça" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "uzunluk" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Biçim:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Nitelik:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Bit oranı:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Acid Jazz" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Acid Rock" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Çevre" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Bluegrass" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Blues" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Oda müziği" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Klasik" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Country" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Death Metal" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Disko" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Kolay Dinleme" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Folk" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Funk" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Gangsta Rap" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Gospel" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Grunge" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Hard Rock" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Heavy Metal" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Hip-hop" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Caz" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Jungle" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Metal" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "New Age" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "New Wave" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Noise" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Pop" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Punk Rock" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Rap" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Reggae" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Rock" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Rock and Roll" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Rhythm and Blues" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Soul" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Swing" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Tekno" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Trip-hop" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Kayıt başarılı" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Kayıt hatası" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Şarkı Bilgisi" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Albüm Sanatçısı" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Yorum" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Parça Numarası" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "_Boş alanları otomatik doldur" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Kaydet" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Önceki" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Sonraki" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "Bilinmiyor" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Atla" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Zamana Atla" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Giriş zamanı (dakika:saniye):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Kuyruğa al" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "Kuyruktan _çıkar" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Şarkıya Atla" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Süzgeç:" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Süzgeç:" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "Geçişten sonra _kapat" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Üzerine Yaz" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Üzerine Yazmayı Onayla" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "%s üzerine yazılsın mı?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Lütfen bir dosya adı uzantısı yazın ya da açılır listeden bir biçim seçin." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Eklentiye Göre Biçim Seç" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Çalma Listesini Dışa Aktar" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Dışa Aktar" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Çalma Listesini İçe Aktar" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_İçe Aktar" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Eklentiler ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "%s Hakkında" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s Ayarları" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Ayarla" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "A_yarlar" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Hakkında" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Dosya Seç" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Klasör Seç" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Görünüm" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Ses" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Ağ" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Çalma Listesi" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Eklentiler" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Gelişmiş" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Genel" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Efekt" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Görselleştirme" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Giriş" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Aktarım" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Albüm sanatçısı" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Parça numarası" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Dosya adı" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Dosya yolu" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Tarih" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Açıklama" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Çözücü" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Nitelik" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Hiçbiri" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Arapça" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Baltık Dili" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Çince" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Yunanca" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "İbranice" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Japonca" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Korece" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Lehçe" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Rusça" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Tayvanca" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Türkçe" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Kendiliğinden" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Kayan noktalı" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Çözüldüğü gibi" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "ReplayGain'i uyguladıktan sonra" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Efekler uygulandıktan sonra" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Dengeleme uygulandıktan sonra" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Karıştırmaya dayalı" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Arayüz:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Çıkış eklentisi:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Tüm dosyaları yükselt:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Etiketsiz dosyaları yükselt:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Çıkış Ayarları" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Bit derinliği:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Arabellek boyutu:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "ms" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "Yumuşak kesim" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Yazılımsal ses denetimi kullan (önerilmez)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Ses Kaydı Ayarları" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Akışı kaydet:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "ReplayGain" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "ReplayGain'i etkinleştir" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Mod:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Tıraşlamayı önle (önerilir)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Vekil sunucu makine adı:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Vekil sunucu bağlantı noktası:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Vekil sunucu kullanıcı adı:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Vekil sunucu şifresi:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Ağ Ayarları" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Vekil Sunucu Yapılandırması" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Vekil sunucu kullanımını etkinleştir" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Vekil sunucu doğrulaması kullan" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "SOCKS vekil kullan" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Şu dil için kendiliğinden karakter tanımlamayı aç:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Alternatif karakter kodlamaları:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Davranış" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Başlangıçta oynatmaya devam et" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Hemen devam etmek yerine duraklat" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "Çalan şarkı silindiğinde sonrakine atla" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Dosya açarken listeyi temizle" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Dosyaları geçici bir listede aç" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Şarkı Göstergesi" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Şarkı numaralarını göster" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Öndeki sıfırları göster (02:00'a karşı 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Saatleri ayrı ayrı göster (1:30:00'a karşı 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Dışa1Dışa aktar" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "Mümkün olduğunda göreli yollar kullanın" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Albüm Resmi" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Bu sözcüklerle eşleşen resimleri ara (virgülle ayır)" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Bu sözcükleri içeren resimleri çıkar (virgülle ayır):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Şarkı dosya adıyla eşleşen resimleri ara" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Yinelemeli ara" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Arama derinliği:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Açılır Bilgi" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Açılır pencere bilgisi göster" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Açılır pencere erteleme (saniyenin onda biri):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Geçerli şarkı için zaman ölçeğini göster" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Uyumluluk" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Geriye yatık taksimi ( \\ ) klasör sınırlayıcı olarak yorumla" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Oynatma Liistesi" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Dizinleri tekrarlı olarak ekle" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Oynatma listesi dosyalarında yuvalanmış dizinler ekle" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Parça Bilgisi" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Eksik üst veriyi dosya yolundan sez" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Çalınana kadar şarkı üst verilerini yükleme" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Tanımlanamayan dosya uzantısı bulunan dosya içeriklerini tara" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Karışık" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "İleri/geri adım:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "saniye" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Ses düzeyini şuna göre ayarlayın:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "yüzde" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "BAŞLIK" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "BAŞLIK - SANATÇI" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "BAŞLIK - SANATÇI - ALBÜM" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "SANATÇI - BAŞLIK" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "SANATÇI - ALBÜM - BAŞLIK" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "SANATÇI - ALBÜM - PARÇA. BAŞLIK" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "SANATÇI [ ALBÜM ] - PARÇA. BAŞLIK" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "ALBÜM - BAŞLIK" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Kategori" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Özel" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Başlık biçimi:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Özel metin:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "%s ile ses akışı kaydını etkinleştir " + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Ses kaydı eklentisi yok" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious Ayarları" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Vazgeç" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Kaydet" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Yükle" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Önayar Dosyası Yükle" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "EQF Dosyası Yükle" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Önayar Dosyasını Kaydet" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "EQF Dosyasını Kaydet" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Kuyruk Yöneticisi" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Sıradan Kaldır" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Çalışıyor..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Hata" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Bilgi" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Geçmişe kaydet" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "URL Aç" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "URL Ekle" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "Geçmişi temiz_le" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "URL gir:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Aç" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Devam eden iletiler gizlendi.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Ön ayarlı dosyalar (* .preset * .eqf * .q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Kapat" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Gözat" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Klasörü Aç" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Klasör Ekle" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Ekle" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Yazı Tipini Ayarla" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Üst veri" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Besteci" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Söyleyen" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Kayıt Yılı" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Kayıt Tarihi" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Teknik" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Bit oranı" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "MusicBrainz Kimliği" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Geri Al" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Etiket(leri) yazma hatası." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "%1 dosya seçildi" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "%1 dosyayı _kaydet" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Düzey" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "İşlev" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "İleti" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Günlük Denetleyici" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Hata giderme" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Bilgi" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Uyarı" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Temizl_e" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Günlük Düzeyi:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Hizmetler" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Kopyala" diff --git a/po/uk.po b/po/uk.po new file mode 100644 index 0000000..d5869a1 --- /dev/null +++ b/po/uk.po @@ -0,0 +1,1521 @@ +# Ukrainian translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Denys, 2014 +# Eugene Paskevich , 2015-2016 +# First Last , 2020 +# Kostyantyn Fedenko , 2011 +# Oleg , 2012 +# NaiLi (aka jamesjames) Rootaerc , 2012 +# NaiLi (aka jamesjames) Rootaerc , 2012 +# Oleg , 2012 +# Rax Garfield , 2012 +# Rax Garfield (http://biokillaz.com/), 2012 +# Rax Garfield , 2012-2013 +# Rustam Tsurik , 2013 +# Rustam Tsurik , 2013 +# Oleg , 2012 +# f6d3887df5c5bcb13fc1d4fb04e37f17, 2017-2018 +# Yaroslav Yenkala , 2016 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-02-06 09:10+0000\n" +"Last-Translator: First Last \n" +"Language-Team: Ukrainian (http://www.transifex.com/audacious/audacious/language/uk/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: uk\n" +"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "Показати довідку командного рядка" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "Показати версію" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "Почати відтворення" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "Призупинити відтворення" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "Призупинити, якщо відтворюється, або почати відтворення" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "Зупинити відтворення" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "Перейти до попередньої пісні" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "Перейти до наступної пісні" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "Додати файли до списку відтворення" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "Додати файли до тимчасового списку відтворення" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "Показати головне вікно" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "Показати вікно \"перейти до пісні\"" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "Запуск без графічного інтерфейсу" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "Вийти при завершенні відтворення" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "Виводити налагоджувальні повідомлення (може використовуватися двічі)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "Запустити у режимі GTK" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "Невідома опція: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "Невідома опція: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "Приклад: audacious [ОПЦІЯ] ... [ФАЙЛ] ...\n\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "Обрати екземпляр для запуску/управління" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "Знайдено %d файл" +msgstr[1] "Знайдено %d файли" +msgstr[2] "Знайдено %d файлів" +msgstr[3] "Знайдено %d файлів" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "Помилка читання %s:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "Файлів не знайдено." + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "Новий список відтворення" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "Стандартний ввід" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "Авдіодиск, стежка %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(помилка кодування)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "Записування потоку має бути налаштоване перед використанням." + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "Помилка відкриття потоку виводу" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "Хиба запису потоку" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "Помилка відтворення %s:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "Хибний авдіоформат" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "Зараз відтворюється" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "Неможливо відкрити %s:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "Помилка завантаження %s." + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "Неможливо завантажити %s: непідтримуване розширення файлу." + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "Помилка завантаження %s." + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "Неможливо зберегти %s: непідтримуване розширення файлу." + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "Помилка завантаження втулку" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "Помилка перемотування" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "Формат файлу не розпізнано" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "Помилка читання метаданих" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "Моно" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "Стерео" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d канал" +msgstr[1] "%d канали" +msgstr[2] "%d каналів" +msgstr[3] "%d каналів" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "Авдіодиск" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "Стежка %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(невідома назва)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "Невідома схема ланки" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "Хибне ім'я файлу" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "Хибний режим доступу" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "Автори" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "Ліцензія" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "Про Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "_Скасувати" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "_Більше не питати" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "Чи ви хочете усунути “%s”?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "_Усунути" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "Усунення списку відтворення" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "Як би Ви хотіли назвати цей список відтворення?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "_Змінити назву" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "Зміна назви списку відтворення" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "Будь ласка оберіть пресет для вивантаження." + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "Файл пресетів ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "Файл налаштувань еквалайзеру ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "Імпортування" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "Експортування" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "Налаштування еквалайзеру" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "Зберегти налаштування" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "Видалити обране" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "Повернути зміни" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "_Увімкнути" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Гц" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Гц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 кГц" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 кГц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 кГц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 кГц" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "18 кГц" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "Еквалайзер" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "Налаштування ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "Скинути на нуль" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "Попереднє підсилення" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "Відкрити файли" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "_Відкрити" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "Закрити _діалог при відкритті" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "Додати файли" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "_Додати" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "Закрити _діалог після додавання" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "_Закрити" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "Назва" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "Виконавець" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "Альбом" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "Напрямок" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "Рік" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "Стежка" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "Тривалість" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "Формат:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "Якість:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "Бітрейт:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "Ейсид-джаз" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "Ейсид-рок" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "Ембієнт" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Бібоп" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "Блуґрас" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "Блюз" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "Камерна музика" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "Класична музика" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "Кантрі" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "Дет-метал" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "Диско" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "Легка музика" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "Народна музика" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "Фанк" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "Ґанґста-реп" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "Ґоспел" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "Ґрандж" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "Гардрок" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "Гевіметал " + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "Гіп-гоп" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "Гавз" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "Джаз" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "Джанґл" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "Метал" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "Ню-ейдж" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "Нова хвиля" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "Нойз" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "Поп-музика" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "Панк-рок" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "Реп" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "Реґей" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "Рок" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "Рок-н-рол" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "Ритм-енд-блюз" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ска" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "Совл" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "Свінг" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "Техно" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "Трип-гоп" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "Збереження успішне" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "Помилка при збереженні" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "Інформація про композицію" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "Виконавець альбому" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "Коментар" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "Номер стежки" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "_Автозаповнення порожніх рядків" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "_Зберегти" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "_Попередній" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "_Наступний" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d кб/с" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "N/A" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "_Перейти" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "Перейти до часу" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "Введіть час (хвилини:секунди):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "_Додати до черги" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "В_илучити з черги" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "Перейти до пісні" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "Фільтр: " + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "_Фільтр: " + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "З_акрити після переходу" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "_Перезаписати" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "Підтвердити перезапис" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "Перезаписати %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "Будь-ласка, введіть розширення файлу, або оберіть формат зі списку." + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "Обрати формат по розширенню" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "Експортувати список відтворення" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "_Експортувати" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "Імпортувати список відтворення" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "_Імпортувати" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "_Втулки ..." + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "Про %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "Налаштування %s" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "_Застосувати" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "_Налаштування" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "_Про" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "Вибрати файл" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "Вибрати теку" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "Зовнішній вигляд" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "Звук" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "Мережа" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "Списки відтворення" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "Втулки" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "Розширені" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "Загальні" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "Ефекти" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "Візуалізація" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "Ввід" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "Транспорт" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "Виконавець альбому" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "Номер стежки" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "Назва файлу" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "Шлях до файлу" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "Дата" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "Опис" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "Кодек" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "Якість" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "Ніякого" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "Арабська" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "Балтійські мови" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "Китайська" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "Грецька" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "Іврит" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "Японська" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "Корейська" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "Польська" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "Російська" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "Тайванська" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "Турецька" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "Автоматично" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "Рухома кома" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "Після декодування" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "Після вирівнювання гучності" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "Після застосування ефектів" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "Після застосування еквалайзера" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "Побудовано на мішаному режимі" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "Вигляд:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "Втулок виведення:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "Підсилювати всі файли:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "дБ" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "Підсилювати непомічені файли:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "Параметри виводу" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "Амплітудна розрядність:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "Розмір буферу:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "мс" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "М’яке відсікання" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "Програмне керування гучністю (не рекомендовано)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "Параметри запису" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "Запис потоку:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "Вирівнювання гучності" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "Увімкнути вирівнювання гучності" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "Режим:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "Запобігати відсіканню (рекомендовано)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "Адреса проксі-серверу:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "Порт:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "Ім'я користувача:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "Гасло:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "Мережеві налаштування" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "КіБ" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "Конфігурація проксі" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "Використовувати проксі" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "Використовувати автентифікацію" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "Використовувати проксі-сервер SOCKS" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "Автовизначення кодування символів:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "Типове кодування символів:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "Поведінка" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "Продовжити відтворення під час запуску" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "Запускати відтворення призупиненим" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "При видаленні поточної пісні відтворювати наступну" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "Очищати список відтворення при відкритті файлів" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "Відкривати файли у тимчасовому списку відтворення" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "Відображення пісні" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "Показувати номер пісні" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "Показувати нульові старші розряди (02:00 замість 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "Показувати розряд годин (1:30:00 замість 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "Експортування" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "За можливістю використовувати схожі шляхи" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "Обкладинка альбому" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "Шукати зображення за цими словами (розділюйте комами):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "Пропускати зображення із цими словами (розділюйте комами):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "Шукати зображення за іменем файлу доріжки" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "Рекурсивний пошук" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "Глибина пошуку:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "Спливна інформація" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "Показувати спливну інформацію" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "Затримка спливання (десяті частки секунди):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "Показувати прогрес відтворення композиції" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "Сумісність" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "Вважати \\ (обернену косу риску) розділювачем тек" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "Список відтворення" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "Додавати теки рекурсивно" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "Додати теки, які вкладені поміж списків відтворення" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Метадані" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "Вгадувати відсутні метадані зі шляху до файлу" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "Не завантажувати метадані доріжок до відтворення" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "Сканувати вміст файлів з невпізнаним розширенням" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "Різне" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "Стрибок уперед/назад на:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "секунд" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "Підлаштувати звук на:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "відсоток" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "НАЗВА" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "НАЗВА - ВИКОНАВЕЦЬ" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "НАЗВА - ВИКОНАВЕЦЬ - АЛЬБОМ" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "ВИКОНАВЕЦЬ - НАЗВА" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "ВИКОНАВЕЦЬ - АЛЬБОМ - НАЗВА" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "ВИКОНАВЕЦЬ - АЛЬБОМ - СТЕЖКА. НАЗВА" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "ВИКОНАВЕЦЬ [ АЛЬБОМ ] СТЕЖКА. НАЗВА" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "АЛЬБОМ - НАЗВА" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "Категорія" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "Власні налаштування" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "Формат назви:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "Власний формат:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "Увімкнено записування потоку з %s" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "Немає втулків для запису авдіо" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Налаштування Audacious" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "Скасувати" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "Зберегти" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "Завантажити" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "Завантажити файл налаштувань" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "Завантажити файл налаштувань еквалайзеру" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "Зберегти файл налаштувань" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "Зберегти файл налаштувань еквалайзеру" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "Керування чергою" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "_Прибрати з черги" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "Опрацювання ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "Помилка" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "Інформація" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "_Зберегти до історії" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "Відкрити адресу" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "Додати адресу" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "О_чистити історію" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "Введіть адресу:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "Відкрити" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(Наступні повідомлення були приховані.)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "Файли пресетів (*.preset *.eqf *.q1)" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "Закрити" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "Огляд..." + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "Відкрити теку" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "Додати теку" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "Додати" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "Налаштувати шрифт" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "Метадані" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "Композитор" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "Виконавець" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "Рік запису" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "Дата запису" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "Технічні" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "Бітрейт" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "MusicBrainz ID" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "_Повернути" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "Помилка під час додавання теґ(ів)." + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "Обрано %1 файлів" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "_Збережено %1 файлів" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "Рівень" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "Функція" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "Повідомлення" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "Інспектор журналу" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "Налагодження " + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "Інформація" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "Попереждення" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "Чис_то" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "Рівень журналювання:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "Служби" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "Копіювати" diff --git a/po/update-potfiles.sh b/po/update-potfiles.sh new file mode 100755 index 0000000..ace2d5c --- /dev/null +++ b/po/update-potfiles.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm POTFILES* +echo "# Please don't update this file manually - use ./update-potfiles.sh instead!" > POTFILES.in +cd .. +find src/ \( -name "*.c" -o -name "*.cxx" -o -name "*.cc" -o -name "*.glade" \) -exec grep -lE "translatable|_\(" \{\} \; | sort | uniq >> po/POTFILES.in diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 0000000..d63e1ba --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,1510 @@ +# Chinese (simplified) translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# Chasye , 2010 +# Mingcong Bai , 2014 +# Mingcong Bai , 2014 +# Luke , 2012 +# Michael Jay Tong , 2014 +# Mingcong Bai , 2016-2017 +# Mingye Wang , 2015 +# Luke , 2012 +# zhangmin , 2013-2015 +# zhangmin , 2013 +# Mingcong Bai , 2015 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-01-26 12:21+0000\n" +"Last-Translator: John Lindgren \n" +"Language-Team: Chinese (China) (http://www.transifex.com/audacious/audacious/language/zh_CN/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh_CN\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "显示命令行帮助" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "显示版本信息" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "开始回放" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "暂停回放" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "暂停/播放" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "停止回放" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "跳回上一曲目" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "跳至下一曲目" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "添加文件到播放列表" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "添加文件到一个临时播放列表" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "显示主界面" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "显示曲目选择窗口" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "不启动图形界面" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "停止播放时退出" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "打印调试信息 (或许需要使用两次)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "未知选项: %s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "未知选项: -%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "用法: audacious [选项] ... [文件] ...\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "选择要运行/控制的实例" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "找到%d个文件" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "读取 %s 时出错:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "未找到额外你就。" + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "新建播放列表" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "标准输入" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "音频CD, 音轨 %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(字符编码错误)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "在使用流录制前必须现在音频设置中配置。" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "打开输出流时出错" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "录制输出流出错" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "播放 %s 时出错:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "不可用音频格式" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "正在播放" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "打开 %s 时错误:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "载入 %s 时出错。" + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "无法载入 %s: 不支持的文件扩展名。" + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "无法保存 %s: 不支持的文件扩展名。" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "加载插件出错" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "定位错误" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "不识别文件格式" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "读取元数据时出错" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "单声道" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "立体声" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d声道" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "音频CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "音轨 %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(未知标题)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "未知 URI 图表" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "无效的文件名" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "无效的访问模式" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "特别鸣谢" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "许可" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "关于Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "取消(_C)" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "不再询问(_D)" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "你希望完全删除 \"%s\" 吗?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "移除(_R)" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "移除播放列表" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "你希望如何称呼这个播放列表?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "重命名(_R)" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "重命名播放列表" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "预设文件 ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF 文件 ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "导入" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "导出" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "均衡器预设" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "保存预设" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "删除选中项" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "复原更改" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "启用(_E)" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "加载" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "均衡器" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "预设 ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "归零" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "前置放大器" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "打开文件" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "打开(_O)" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "打开时关闭对话框(_D)" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "添加文件" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "添加(_A)" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "添加时关闭对话框(_D)" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "关闭(_C)" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "标题" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "艺术家" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "专辑" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "风格" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "年份" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "音轨" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "长度" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "格式: " + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "音质: " + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "比特率: " + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "迷幻爵士乐" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "酸性摇滚" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "氛围音乐" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "比波普爵士乐" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "蓝草音乐" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "蓝调" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "室内音乐" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "古典" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "乡村音乐" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "死亡金属" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "迪斯科" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "轻音乐" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "民谣" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "放克" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "匪帮说唱" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "福音音乐" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "垃圾摇滚" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "硬摇滚" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "重金属" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "嘻哈音乐" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr " 浩室舞曲" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "爵士" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "丛林音乐" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "金属" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "新世纪" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "新浪潮" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "噪音音乐" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "流行" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "朋克摇滚乐" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "说唱" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "雷盖舞曲" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "摇滚" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "摇滚乐" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "节奏布鲁斯音乐" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "斯卡" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "灵魂乐" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr " 摇摆乐" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr " 电子舞曲" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "神游舞曲" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "保存成功" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "保存出错" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "歌曲信息" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "专辑艺术家" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "备注" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "音轨序号" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "保存(_S)" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "下一首(_N)" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "不可用" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "跳至(_J)" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "跳到时间" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "输入时间 (分:秒):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "入队(_Q)" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "出列(_Q)" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "跳到歌曲" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "过滤器:" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "过滤器(_F):" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "跳转时关闭 (_C)" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "覆盖(_O)" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "确定覆盖" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "是否覆盖 %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "请输入一个文件扩展名或从下拉列表选择一个文件格式。" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "根据扩展名选择格式" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "导出播放列表" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "导出(_E)" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "导入播放列表" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "导入(_I)" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "插件... (_P)" + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "关于 %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s 设置" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "设置 (_S)" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "设置 (_S)" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "关于 (_A)" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "选择文件" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "选择文件夹" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "外观" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "音频" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "网络" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "播放列表" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "插件" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "一般" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "音效" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "虚拟效果" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "输入" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "传输" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "专辑艺术家" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "音轨序号" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "文件名" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "文件路径" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "时间" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "编码" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "音质" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "无" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "阿拉伯语" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "波罗的语" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "汉语" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "希腊语" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "希伯来语" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "日语" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "韩语" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "波兰语" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "俄语" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "台语" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "土耳其语" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "自动" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "浮点" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "与解码后一致" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "应用回放增益后" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "应用特效后" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "应用均衡后" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "基于随机播放" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "界面:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "输出插件:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "应用到文件:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "dB" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "应用到无标签文件:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "输出设置" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "位深:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "缓冲大小:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "毫秒" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "柔性剪峰" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "使用软音量控制(非建议)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "录制设置" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "录制流:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "回放增益" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "启用回放增益" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "模式:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "避免爆音(推荐)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "主机地址:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "连接端口:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "认证用户:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "认证密码:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "网络设置" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "代理服务器设置" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "启用代理服务器" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "代理服务器要求认证" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "自动检测下列编码:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "备用字符编码:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "行为" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "启动时恢复播放" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "立刻暂停,而不是继续播放" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "歌曲播放中被删除则播放下一首" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "打开文件时清空当前播放列表" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "在临时播放列表打开文件" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "歌曲显示" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "显示歌曲序号" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "显示开头的 0(02:00 或 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "单独显示小时(1:30:00 或 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "专辑封面" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "搜索匹配以下词语的图片(用逗号分隔):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "排除匹配以下词语的图片(用逗号分隔):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "搜索匹配歌曲文件名的图片" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "递归搜索" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "搜索深度:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "弹出信息" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "显示弹出信息" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "弹出延迟 (十分之一秒):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "停止播放" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "兼容性" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "说明 \\(反斜杠)作为一个文件夹分隔符" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "Metadata" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "从文件路径猜测缺失的元数据" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "未播放时切勿加载元数据" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "待检测文件包含不能识别的文件扩展名" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "杂项" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "秒" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "标题" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "标题 - 艺术家" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr " 标题 - 艺术家 - 专辑" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "艺术家 - 标题" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "艺术家 - 专辑 - 标题" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "艺术家 - 专辑 - 曲目号. 标题" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "艺术家 [专辑] - 曲目号. 标题" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "专辑 - 标题" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "分类" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "自定义" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "标题样式:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "自定字符:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "使用 %s 开启音频流录制" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "无可用的音频录制插件" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious 设置" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "取消" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "保存" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "载入" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "载入预设文件" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "载入 EQF 文件" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "保存预设文件" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "保存 EQF 文件" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "队列管理器" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "从队列移除 (_U)" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "进行中..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "错误" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "信息" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "打开URL" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "添加URL" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "输入地址" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "打开" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(详细信息已隐藏。)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "关闭" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "浏览" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "打开文件夹" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "添加文件夹" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "添加" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "元数据" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "作曲" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "演奏" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "录制年代" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "录制日期" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "技术员" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "比特率" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "级别" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "功能" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "消息" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "日志监视器" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "调试" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "信息" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "警告" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "清空(_E)" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "日志级别:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "服务" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "复制" diff --git a/po/zh_TW.po b/po/zh_TW.po new file mode 100644 index 0000000..ecdcf4d --- /dev/null +++ b/po/zh_TW.po @@ -0,0 +1,1506 @@ +# Chinese (traditional) translation for Audacious +# Copyright (C) Audacious translators +# This file is distributed under the same license as the Audacious package. +# +# Translators: +# byStarTW (pan93412) , 2019 +# Ruei-Yuan Lu , 2011 +# whhone , 2013 +# whhone , 2013 +# whhone , 2013 +# 盧瑞元 , 2020 +# 盧瑞元 , 2016-2017,2019 +msgid "" +msgstr "" +"Project-Id-Version: Audacious\n" +"Report-Msgid-Bugs-To: https://redmine.audacious-media-player.org/\n" +"POT-Creation-Date: 2020-01-26 13:17+0100\n" +"PO-Revision-Date: 2020-03-24 03:33+0000\n" +"Last-Translator: 盧瑞元 \n" +"Language-Team: Chinese (Taiwan) (http://www.transifex.com/audacious/audacious/language/zh_TW/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: zh_TW\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/audacious/main.cc:65 +msgid "Show command-line help" +msgstr "顯示命令列的求助訊息" + +#: src/audacious/main.cc:66 +msgid "Show version" +msgstr "顯示版本資訊" + +#: src/audacious/main.cc:67 +msgid "Start playback" +msgstr "開始播放" + +#: src/audacious/main.cc:68 +msgid "Pause playback" +msgstr "暫停播放" + +#: src/audacious/main.cc:69 +msgid "Pause if playing, play otherwise" +msgstr "在播放與暫停之間的切換" + +#: src/audacious/main.cc:70 +msgid "Stop playback" +msgstr "停止播放" + +#: src/audacious/main.cc:71 +msgid "Skip to previous song" +msgstr "跳到上一首歌曲" + +#: src/audacious/main.cc:72 +msgid "Skip to next song" +msgstr "跳到下一首歌曲" + +#: src/audacious/main.cc:73 +msgid "Add files to the playlist" +msgstr "加入檔案到播放清單" + +#: src/audacious/main.cc:74 +msgid "Add files to a temporary playlist" +msgstr "加入檔案到暫存的播放清單" + +#: src/audacious/main.cc:75 +msgid "Display the main window" +msgstr "顯示主視窗" + +#: src/audacious/main.cc:76 +msgid "Display the jump-to-song window" +msgstr "顯示跳轉視窗" + +#: src/audacious/main.cc:77 +msgid "Start without a graphical interface" +msgstr "以隱匿模式啟動" + +#: src/audacious/main.cc:78 +msgid "Quit on playback stop" +msgstr "播放停止後離開" + +#: src/audacious/main.cc:79 +msgid "Print debugging messages (may be used twice)" +msgstr "顯示除錯訊息 (也許需要輸入兩次)" + +#: src/audacious/main.cc:81 +msgid "Run in GTK mode" +msgstr "以 GTK 模式啟動" + +#: src/audacious/main.cc:138 +#, c-format +msgid "Unknown option: %s\n" +msgstr "未知的選項:%s\n" + +#: src/audacious/main.cc:160 +#, c-format +msgid "Unknown option: -%c\n" +msgstr "未知的選項:-%c\n" + +#: src/audacious/main.cc:184 +msgid "" +"Usage: audacious [OPTION] ... [FILE] ...\n" +"\n" +msgstr "使用方式:audacious [選項] ... [檔案] ...\n" + +#: src/audacious/main.cc:185 +msgid "Select instance to run/control" +msgstr "選擇要執行或控制的播放器" + +#: src/audacious/main.cc:365 src/libaudqt/audqt.cc:64 +msgid "Audacious" +msgstr "Audacious" + +#: src/libaudcore/adder.cc:96 +#, c-format +msgid "%d file found" +msgid_plural "%d files found" +msgstr[0] "找到 %d 個檔案" + +#: src/libaudcore/adder.cc:320 src/libaudcore/adder.cc:402 +#, c-format +msgid "" +"Error reading %s:\n" +"%s" +msgstr "讀取 %s 時發生錯誤:\n%s" + +#: src/libaudcore/adder.cc:454 +msgid "No files found." +msgstr "找不到檔案。" + +#: src/libaudcore/adder.cc:476 src/libaudcore/playlist.cc:81 +msgid "New Playlist" +msgstr "新播放清單" + +#: src/libaudcore/audstrings.cc:664 src/libaudcore/tuple.cc:524 +msgid "Standard input" +msgstr "標準輸入" + +#: src/libaudcore/audstrings.cc:666 +#, c-format +msgid "Audio CD, track %s" +msgstr "音樂 CD,音軌 %s" + +#: src/libaudcore/audstrings.cc:670 src/libaudcore/tuple.cc:500 +msgid "(character encoding error)" +msgstr "(字元編碼錯誤)" + +#: src/libaudcore/drct.cc:96 +msgid "" +"Stream recording must be configured in Audio Settings before it can be used." +msgstr "您必須先在音訊設定中設定串流錄音才能使用。" + +#: src/libaudcore/output.cc:289 +msgid "Error opening output stream" +msgstr "開啟輸出串流時發生錯誤" + +#: src/libaudcore/output.cc:341 +msgid "Error recording output stream" +msgstr "錄製輸出串流時發生錯誤" + +#: src/libaudcore/playback.cc:379 +#, c-format +msgid "" +"Error playing %s:\n" +"%s" +msgstr "播放 %s 時發生錯誤:\n%s" + +#: src/libaudcore/playback.cc:510 +msgid "Invalid audio format" +msgstr "無效的音訊格式" + +#: src/libaudcore/playlist.cc:82 +msgid "Now Playing" +msgstr "正在播放" + +#: src/libaudcore/playlist-files.cc:73 src/libaudcore/playlist-files.cc:153 +#: src/libaudgui/infowin.cc:509 src/libaudqt/infowin-qt.cc:248 +#, c-format +msgid "" +"Error opening %s:\n" +"%s" +msgstr "開啟 %s 時發生錯誤:\n%s" + +#: src/libaudcore/playlist-files.cc:87 src/libaudqt/eq-preset-qt.cc:276 +#, c-format +msgid "Error loading %s." +msgstr "載入 %s 時發生錯誤。" + +#: src/libaudcore/playlist-files.cc:89 +#, c-format +msgid "Cannot load %s: unsupported file name extension." +msgstr "無法載入 %s:不支援該副檔名。" + +#: src/libaudcore/playlist-files.cc:161 src/libaudqt/eq-preset-qt.cc:309 +#, c-format +msgid "Error saving %s." +msgstr "儲存 %s 時發生錯誤。" + +#: src/libaudcore/playlist-files.cc:167 +#, c-format +msgid "Cannot save %s: unsupported file name extension." +msgstr "無法儲存 %s:不支援該副檔名。" + +#: src/libaudcore/probe.cc:54 +msgid "Error loading plugin" +msgstr "載入外掛時發生錯誤" + +#: src/libaudcore/probe.cc:173 +msgid "Seek error" +msgstr "搜尋發生錯誤" + +#: src/libaudcore/probe.cc:181 +msgid "File format not recognized" +msgstr "無法辨識檔案格式" + +#: src/libaudcore/probe.cc:210 +msgid "Error reading metadata" +msgstr "讀取詮釋資料時發生錯誤" + +#: src/libaudcore/tuple.cc:558 +msgid "Mono" +msgstr "單聲道" + +#: src/libaudcore/tuple.cc:560 +msgid "Stereo" +msgstr "立體聲" + +#: src/libaudcore/tuple.cc:563 +#, c-format +msgid "%d channel" +msgid_plural "%d channels" +msgstr[0] "%d 聲道" + +#: src/libaudcore/tuple.cc:777 +msgid "Audio CD" +msgstr "音訊 CD" + +#: src/libaudcore/tuple.cc:861 +#, c-format +msgid "Track %d" +msgstr "音軌 %d" + +#: src/libaudcore/tuple.cc:867 +msgid "(unknown title)" +msgstr "(未知的標題)" + +#: src/libaudcore/vfs.cc:79 +msgid "Unknown URI scheme" +msgstr "未知的連結格式" + +#: src/libaudcore/vfs_local.cc:86 src/libaudcore/vfs_local.cc:330 +#: src/libaudcore/vfs_local.cc:386 +msgid "Invalid file name" +msgstr "無效的檔案名稱" + +#: src/libaudcore/vfs_local.cc:134 +msgid "Invalid access mode" +msgstr "無效的存取模式" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "Credits" +msgstr "開發團隊" + +#: src/libaudgui/about.cc:36 src/libaudqt/about-qt.cc:36 +msgid "License" +msgstr "授權條款" + +#: src/libaudgui/about.cc:72 src/libaudqt/about-qt.cc:63 +msgid "About Audacious" +msgstr "關於 Audacious" + +#: src/libaudgui/confirm.cc:36 src/libaudgui/jump-to-time.cc:48 +#: src/libaudgui/playlists.cc:92 src/libaudgui/playlists.cc:189 +#: src/libaudgui/plugin-prefs.cc:160 src/libaudgui/url-opener.cc:101 +#: src/libaudqt/playlist-management.cc:41 +#: src/libaudqt/playlist-management.cc:59 src/libaudqt/prefs-plugin.cc:136 +#: src/libaudqt/url-opener-qt.cc:79 +msgid "_Cancel" +msgstr "取消(_C)" + +#: src/libaudgui/confirm.cc:51 src/libaudqt/playlist-management.cc:57 +msgid "_Don’t ask again" +msgstr "不再詢問(_D)" + +#: src/libaudgui/confirm.cc:70 src/libaudqt/playlist-management.cc:64 +#, c-format +msgid "Do you want to permanently remove “%s”?" +msgstr "您確定要永久地移除「%s」?" + +#: src/libaudgui/confirm.cc:73 src/libaudqt/playlist-management.cc:58 +msgid "_Remove" +msgstr "移除(_R)" + +#: src/libaudgui/confirm.cc:76 src/libaudqt/playlist-management.cc:62 +msgid "Remove Playlist" +msgstr "移除播放清單" + +#: src/libaudgui/confirm.cc:95 src/libaudqt/playlist-management.cc:39 +msgid "What would you like to call this playlist?" +msgstr "您希望怎麼命名這份播放清單?" + +#: src/libaudgui/confirm.cc:96 src/libaudqt/playlist-management.cc:40 +msgid "_Rename" +msgstr "重新命名(_R)" + +#: src/libaudgui/confirm.cc:97 src/libaudqt/playlist-management.cc:38 +msgid "Rename Playlist" +msgstr "重新命名播放清單" + +#: src/libaudgui/eq-preset.cc:153 +msgid "Please select one preset to export." +msgstr "" + +#: src/libaudgui/eq-preset.cc:256 src/libaudgui/eq-preset.cc:261 +msgid "Preset File ..." +msgstr "預設集檔案 ..." + +#: src/libaudgui/eq-preset.cc:257 src/libaudgui/eq-preset.cc:262 +msgid "EQF File ..." +msgstr "EQF 檔案 ..." + +#: src/libaudgui/eq-preset.cc:266 src/libaudqt/eq-preset-qt.cc:331 +#: src/libaudqt/fileopener.cc:63 +msgid "Import" +msgstr "匯入" + +#: src/libaudgui/eq-preset.cc:267 src/libaudqt/eq-preset-qt.cc:334 +#: src/libaudqt/fileopener.cc:63 +msgid "Export" +msgstr "匯出" + +#: src/libaudgui/eq-preset.cc:282 src/libaudqt/eq-preset-qt.cc:319 +msgid "Equalizer Presets" +msgstr "等化器預設集" + +#: src/libaudgui/eq-preset.cc:304 src/libaudqt/eq-preset-qt.cc:323 +msgid "Save Preset" +msgstr "儲存預設集" + +#: src/libaudgui/eq-preset.cc:326 +msgid "Delete Selected" +msgstr "刪除選擇的項目" + +#: src/libaudgui/eq-preset.cc:330 src/libaudqt/eq-preset-qt.cc:344 +msgid "Revert Changes" +msgstr "取消變更" + +#: src/libaudgui/equalizer.cc:45 src/libaudqt/equalizer-qt.cc:116 +msgid "_Enable" +msgstr "啟用(_E)" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "31 Hz" +msgstr "31 Hz" + +#: src/libaudgui/equalizer.cc:124 src/libaudqt/equalizer-qt.cc:119 +msgid "63 Hz" +msgstr "63 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "125 Hz" +msgstr "125 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "250 Hz" +msgstr "250 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:119 +msgid "500 Hz" +msgstr "500 Hz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "1 kHz" +msgstr "1 kHz" + +#: src/libaudgui/equalizer.cc:125 src/libaudqt/equalizer-qt.cc:120 +msgid "2 kHz" +msgstr "2 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "4 kHz" +msgstr "4 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "8 kHz" +msgstr "8 kHz" + +#: src/libaudgui/equalizer.cc:126 src/libaudqt/equalizer-qt.cc:120 +msgid "16 kHz" +msgstr "16 kHz" + +#: src/libaudgui/equalizer.cc:129 src/libaudqt/equalizer-qt.cc:153 +msgid "Equalizer" +msgstr "等化器" + +#: src/libaudgui/equalizer.cc:143 src/libaudqt/equalizer-qt.cc:140 +msgid "Presets ..." +msgstr "預設集 ..." + +#: src/libaudgui/equalizer.cc:147 src/libaudqt/equalizer-qt.cc:139 +msgid "Reset to Zero" +msgstr "重設為零" + +#: src/libaudgui/equalizer.cc:154 src/libaudqt/equalizer-qt.cc:125 +msgid "Preamp" +msgstr "前置放大" + +#: src/libaudgui/file-opener.cc:78 src/libaudqt/fileopener.cc:58 +msgid "Open Files" +msgstr "開啟檔案" + +#: src/libaudgui/file-opener.cc:79 src/libaudgui/url-opener.cc:64 +#: src/libaudqt/url-opener-qt.cc:47 +msgid "_Open" +msgstr "開啟(_O)" + +#: src/libaudgui/file-opener.cc:81 +msgid "Close _dialog on open" +msgstr "開啟後關閉對話視窗(_D)" + +#: src/libaudgui/file-opener.cc:86 src/libaudqt/fileopener.cc:58 +msgid "Add Files" +msgstr "加入檔案" + +#: src/libaudgui/file-opener.cc:87 src/libaudgui/url-opener.cc:70 +#: src/libaudqt/url-opener-qt.cc:53 +msgid "_Add" +msgstr "加入(_A)" + +#: src/libaudgui/file-opener.cc:89 +msgid "Close _dialog on add" +msgstr "加入後關閉對話視窗(_D)" + +#: src/libaudgui/file-opener.cc:128 src/libaudgui/infowin.cc:414 +#: src/libaudgui/jump-to-track.cc:309 src/libaudgui/plugin-prefs.cc:166 +#: src/libaudgui/prefs-window.cc:894 src/libaudgui/queue-manager.cc:194 +#: src/libaudgui/util.cc:297 src/libaudqt/audqt.cc:229 +#: src/libaudqt/infowin-qt.cc:155 src/libaudqt/log-inspector.cc:242 +#: src/libaudqt/prefs-plugin.cc:147 src/libaudqt/prefs-window-qt.cc:625 +#: src/libaudqt/queue-manager-qt.cc:162 +msgid "_Close" +msgstr "關閉(_C)" + +#: src/libaudgui/infopopup.cc:187 src/libaudgui/infowin.cc:369 +#: src/libaudgui/prefs-window.cc:104 src/libaudqt/infopopup-qt.cc:93 +#: src/libaudqt/info-widget.cc:48 src/libaudqt/prefs-window-qt.cc:167 +msgid "Title" +msgstr "標題" + +#: src/libaudgui/infopopup.cc:188 src/libaudgui/infowin.cc:372 +#: src/libaudgui/prefs-window.cc:101 src/libaudqt/infopopup-qt.cc:95 +#: src/libaudqt/info-widget.cc:49 src/libaudqt/prefs-window-qt.cc:164 +msgid "Artist" +msgstr "藝人" + +#: src/libaudgui/infopopup.cc:189 src/libaudgui/infowin.cc:375 +#: src/libaudgui/prefs-window.cc:102 src/libaudgui/prefs-window.cc:149 +#: src/libaudqt/infopopup-qt.cc:97 src/libaudqt/info-widget.cc:50 +#: src/libaudqt/prefs-window-qt.cc:165 src/libaudqt/prefs-window-qt.cc:207 +msgid "Album" +msgstr "專輯" + +#: src/libaudgui/infopopup.cc:190 src/libaudgui/infowin.cc:385 +#: src/libaudgui/prefs-window.cc:106 src/libaudqt/infopopup-qt.cc:99 +#: src/libaudqt/info-widget.cc:53 src/libaudqt/prefs-window-qt.cc:169 +msgid "Genre" +msgstr "類型" + +#: src/libaudgui/infopopup.cc:191 src/libaudgui/infowin.cc:388 +#: src/libaudgui/prefs-window.cc:111 src/libaudqt/infopopup-qt.cc:101 +#: src/libaudqt/prefs-window-qt.cc:174 +msgid "Year" +msgstr "年份" + +#: src/libaudgui/infopopup.cc:192 src/libaudgui/prefs-window.cc:148 +#: src/libaudqt/infopopup-qt.cc:103 src/libaudqt/prefs-window-qt.cc:206 +msgid "Track" +msgstr "音軌" + +#: src/libaudgui/infopopup.cc:193 src/libaudqt/infopopup-qt.cc:105 +#: src/libaudqt/info-widget.cc:63 +msgid "Length" +msgstr "長度" + +#: src/libaudgui/infowin.cc:50 +msgid "Format:" +msgstr "標題格式:" + +#: src/libaudgui/infowin.cc:51 +msgid "Quality:" +msgstr "品質:" + +#: src/libaudgui/infowin.cc:52 +msgid "Bitrate:" +msgstr "位元率:" + +#: src/libaudgui/infowin.cc:86 +msgid "Acid Jazz" +msgstr "迷幻爵士" + +#: src/libaudgui/infowin.cc:87 +msgid "Acid Rock" +msgstr "迷幻搖滾" + +#: src/libaudgui/infowin.cc:88 +msgid "Ambient" +msgstr "氛圍音樂" + +#: src/libaudgui/infowin.cc:89 +msgid "Bebop" +msgstr "Bebop" + +#: src/libaudgui/infowin.cc:90 +msgid "Bluegrass" +msgstr "藍草" + +#: src/libaudgui/infowin.cc:91 +msgid "Blues" +msgstr "藍調" + +#: src/libaudgui/infowin.cc:92 +msgid "Chamber Music" +msgstr "室內樂" + +#: src/libaudgui/infowin.cc:93 +msgid "Classical" +msgstr "古典" + +#: src/libaudgui/infowin.cc:94 +msgid "Country" +msgstr "鄉村" + +#: src/libaudgui/infowin.cc:95 +msgid "Death Metal" +msgstr "死亡金屬" + +#: src/libaudgui/infowin.cc:96 +msgid "Disco" +msgstr "迪斯可" + +#: src/libaudgui/infowin.cc:97 +msgid "Easy Listening" +msgstr "輕音樂" + +#: src/libaudgui/infowin.cc:98 +msgid "Folk" +msgstr "民謠" + +#: src/libaudgui/infowin.cc:99 +msgid "Funk" +msgstr "放客" + +#: src/libaudgui/infowin.cc:100 +msgid "Gangsta Rap" +msgstr "黑幫說唱" + +#: src/libaudgui/infowin.cc:101 +msgid "Gospel" +msgstr "福音音樂" + +#: src/libaudgui/infowin.cc:102 +msgid "Grunge" +msgstr "垃圾搖滾" + +#: src/libaudgui/infowin.cc:103 +msgid "Hard Rock" +msgstr "硬式搖滾" + +#: src/libaudgui/infowin.cc:104 +msgid "Heavy Metal" +msgstr "重金屬" + +#: src/libaudgui/infowin.cc:105 +msgid "Hip-hop" +msgstr "嘻哈" + +#: src/libaudgui/infowin.cc:106 +msgid "House" +msgstr "House" + +#: src/libaudgui/infowin.cc:107 +msgid "Jazz" +msgstr "爵士" + +#: src/libaudgui/infowin.cc:108 +msgid "Jungle" +msgstr "叢林" + +#: src/libaudgui/infowin.cc:109 +msgid "Metal" +msgstr "金屬" + +#: src/libaudgui/infowin.cc:110 +msgid "New Age" +msgstr "新世紀" + +#: src/libaudgui/infowin.cc:111 +msgid "New Wave" +msgstr "新浪潮" + +#: src/libaudgui/infowin.cc:112 +msgid "Noise" +msgstr "噪音" + +#: src/libaudgui/infowin.cc:113 +msgid "Pop" +msgstr "流行" + +#: src/libaudgui/infowin.cc:114 +msgid "Punk Rock" +msgstr "龐克搖滾" + +#: src/libaudgui/infowin.cc:115 +msgid "Rap" +msgstr "說唱" + +#: src/libaudgui/infowin.cc:116 +msgid "Reggae" +msgstr "雷鬼" + +#: src/libaudgui/infowin.cc:117 +msgid "Rock" +msgstr "搖滾 (Rock)" + +#: src/libaudgui/infowin.cc:118 +msgid "Rock and Roll" +msgstr "搖滾 (Rock&Roll)" + +#: src/libaudgui/infowin.cc:119 +msgid "Rhythm and Blues" +msgstr "R&B" + +#: src/libaudgui/infowin.cc:120 +msgid "Ska" +msgstr "Ska" + +#: src/libaudgui/infowin.cc:121 +msgid "Soul" +msgstr "靈魂" + +#: src/libaudgui/infowin.cc:122 +msgid "Swing" +msgstr "搖擺樂" + +#: src/libaudgui/infowin.cc:123 +msgid "Techno" +msgstr "數位" + +#: src/libaudgui/infowin.cc:124 +msgid "Trip-hop" +msgstr "迷幻舞曲" + +#: src/libaudgui/infowin.cc:227 +msgid "Save successful" +msgstr "儲存成功" + +#: src/libaudgui/infowin.cc:231 +msgid "Save error" +msgstr "儲存失敗" + +#: src/libaudgui/infowin.cc:324 src/libaudgui/prefs-window.cc:86 +#: src/libaudqt/infowin-qt.cc:120 src/libaudqt/prefs-window-qt.cc:159 +msgid "Song Info" +msgstr "歌曲資訊" + +#: src/libaudgui/infowin.cc:378 src/libaudqt/info-widget.cc:51 +msgid "Album Artist" +msgstr "專輯藝人" + +#: src/libaudgui/infowin.cc:381 src/libaudgui/prefs-window.cc:112 +#: src/libaudqt/info-widget.cc:54 src/libaudqt/prefs-window-qt.cc:175 +msgid "Comment" +msgstr "備註" + +#: src/libaudgui/infowin.cc:391 src/libaudqt/info-widget.cc:52 +msgid "Track Number" +msgstr "音軌編號" + +#: src/libaudgui/infowin.cc:397 +msgid "_Auto-fill empty fields" +msgstr "" + +#: src/libaudgui/infowin.cc:411 src/libaudqt/infowin-qt.cc:183 +msgid "_Save" +msgstr "儲存(_S)" + +#: src/libaudgui/infowin.cc:417 +msgid "_Previous" +msgstr "" + +#: src/libaudgui/infowin.cc:420 +msgid "_Next" +msgstr "下一個(_N)" + +#: src/libaudgui/infowin.cc:469 +#, c-format +msgid "%d kb/s" +msgstr "%d kb/s" + +#: src/libaudgui/infowin.cc:474 +msgid "N/A" +msgstr "無" + +#: src/libaudgui/jump-to-time.cc:47 src/libaudgui/jump-to-track.cc:314 +msgid "_Jump" +msgstr "跳轉(_J)" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Jump to Time" +msgstr "跳轉到指定時間" + +#: src/libaudgui/jump-to-time.cc:51 +msgid "Enter time (minutes:seconds):" +msgstr "請輸入時間 (分:秒):" + +#: src/libaudgui/jump-to-track.cc:95 src/libaudgui/jump-to-track.cc:103 +#: src/libaudgui/jump-to-track.cc:305 +msgid "_Queue" +msgstr "排入佇列(_Q)" + +#: src/libaudgui/jump-to-track.cc:101 +msgid "Un_queue" +msgstr "移出佇列(_Q)" + +#: src/libaudgui/jump-to-track.cc:240 +msgid "Jump to Song" +msgstr "跳轉到指定歌曲" + +#: src/libaudgui/jump-to-track.cc:265 +msgid "Filter: " +msgstr "過濾器:" + +#: src/libaudgui/jump-to-track.cc:266 +msgid "_Filter:" +msgstr "過濾器(_F):" + +#: src/libaudgui/jump-to-track.cc:298 +msgid "C_lose on jump" +msgstr "切換後關閉(_C)" + +#: src/libaudgui/playlists.cc:91 +msgid "_Overwrite" +msgstr "覆寫(_O)" + +#: src/libaudgui/playlists.cc:95 +msgid "Confirm Overwrite" +msgstr "確認是否覆寫" + +#: src/libaudgui/playlists.cc:95 +#, c-format +msgid "Overwrite %s?" +msgstr "覆寫 %s?" + +#: src/libaudgui/playlists.cc:121 +msgid "" +"Please type a filename extension or select a format from the drop-down list." +msgstr "請輸入副檔名或者從下拉式清單中選擇檔案格式。" + +#: src/libaudgui/playlists.cc:140 +msgid "Select Format by Extension" +msgstr "依副檔名選擇對應的格式" + +#: src/libaudgui/playlists.cc:167 src/libaudqt/fileopener.cc:59 +msgid "Export Playlist" +msgstr "匯出播放清單" + +#: src/libaudgui/playlists.cc:168 +msgid "_Export" +msgstr "匯出(_E)" + +#: src/libaudgui/playlists.cc:174 src/libaudqt/fileopener.cc:59 +msgid "Import Playlist" +msgstr "匯入播放清單" + +#: src/libaudgui/playlists.cc:175 +msgid "_Import" +msgstr "匯入(_I)" + +#: src/libaudgui/plugin-menu.cc:40 src/libaudqt/plugin-menu-qt.cc:44 +msgid "_Plugins ..." +msgstr "外掛(_P)" + +#: src/libaudgui/plugin-prefs.cc:109 src/libaudqt/prefs-plugin.cc:57 +#, c-format +msgid "About %s" +msgstr "關於 %s" + +#: src/libaudgui/plugin-prefs.cc:155 src/libaudqt/prefs-plugin.cc:122 +#, c-format +msgid "%s Settings" +msgstr "%s 設定" + +#: src/libaudgui/plugin-prefs.cc:159 src/libaudqt/prefs-plugin.cc:134 +msgid "_Set" +msgstr "套用(_S)" + +#: src/libaudgui/plugin-view.cc:235 src/libaudgui/prefs-window.cc:708 +#: src/libaudgui/prefs-window.cc:748 src/libaudqt/prefs-window-qt.cc:580 +#: src/libaudqt/prefs-window-qt.cc:583 +msgid "_Settings" +msgstr "設定(_S)" + +#: src/libaudgui/plugin-view.cc:242 src/libaudgui/prefs-window.cc:722 +#: src/libaudgui/prefs-window.cc:760 src/libaudqt/prefs-window-qt.cc:581 +#: src/libaudqt/prefs-window-qt.cc:584 +msgid "_About" +msgstr "關於(_A)" + +#: src/libaudgui/prefs-widget.cc:277 src/libaudqt/prefs-widget-qt.cc:235 +msgid "Choose File" +msgstr "選擇檔案" + +#: src/libaudgui/prefs-widget.cc:281 src/libaudqt/prefs-widget-qt.cc:239 +msgid "Choose Folder" +msgstr "選擇資料夾" + +#: src/libaudgui/prefs-window.cc:82 src/libaudqt/prefs-window-qt.cc:155 +msgid "Appearance" +msgstr "外觀" + +#: src/libaudgui/prefs-window.cc:83 src/libaudqt/prefs-window-qt.cc:156 +msgid "Audio" +msgstr "音訊" + +#: src/libaudgui/prefs-window.cc:84 src/libaudqt/prefs-window-qt.cc:157 +msgid "Network" +msgstr "網路" + +#: src/libaudgui/prefs-window.cc:85 src/libaudgui/prefs-window.cc:96 +#: src/libaudqt/prefs-pluginlist-model.cc:43 +#: src/libaudqt/prefs-window-qt.cc:158 +msgid "Playlist" +msgstr "播放清單" + +#: src/libaudgui/prefs-window.cc:87 src/libaudqt/prefs-window-qt.cc:160 +msgid "Plugins" +msgstr "外掛" + +#: src/libaudgui/prefs-window.cc:88 src/libaudqt/prefs-window-qt.cc:161 +msgid "Advanced" +msgstr "進階" + +#: src/libaudgui/prefs-window.cc:92 src/libaudqt/prefs-pluginlist-model.cc:39 +msgid "General" +msgstr "一般" + +#: src/libaudgui/prefs-window.cc:93 src/libaudqt/prefs-pluginlist-model.cc:40 +msgid "Effect" +msgstr "特效" + +#: src/libaudgui/prefs-window.cc:94 src/libaudqt/prefs-pluginlist-model.cc:41 +msgid "Visualization" +msgstr "視覺特效" + +#: src/libaudgui/prefs-window.cc:95 src/libaudqt/prefs-pluginlist-model.cc:42 +msgid "Input" +msgstr "輸入" + +#: src/libaudgui/prefs-window.cc:97 src/libaudqt/prefs-pluginlist-model.cc:44 +msgid "Transport" +msgstr "傳輸" + +#: src/libaudgui/prefs-window.cc:103 src/libaudqt/prefs-window-qt.cc:166 +msgid "Album artist" +msgstr "專輯藝人" + +#: src/libaudgui/prefs-window.cc:105 src/libaudqt/prefs-window-qt.cc:168 +msgid "Track number" +msgstr "音軌編號" + +#: src/libaudgui/prefs-window.cc:107 src/libaudqt/prefs-window-qt.cc:170 +msgid "File name" +msgstr "檔案名稱" + +#: src/libaudgui/prefs-window.cc:108 src/libaudqt/prefs-window-qt.cc:171 +msgid "File path" +msgstr "檔案路徑" + +#: src/libaudgui/prefs-window.cc:109 src/libaudqt/prefs-window-qt.cc:172 +msgid "Date" +msgstr "日期" + +#: src/libaudgui/prefs-window.cc:110 src/libaudqt/info-widget.cc:55 +#: src/libaudqt/prefs-window-qt.cc:173 +msgid "Description" +msgstr "說明" + +#: src/libaudgui/prefs-window.cc:113 src/libaudqt/info-widget.cc:64 +#: src/libaudqt/prefs-window-qt.cc:176 +msgid "Codec" +msgstr "編解碼器" + +#: src/libaudgui/prefs-window.cc:114 src/libaudqt/info-widget.cc:65 +#: src/libaudqt/prefs-window-qt.cc:177 +msgid "Quality" +msgstr "品質" + +#: src/libaudgui/prefs-window.cc:118 src/libaudqt/prefs-window-qt.cc:180 +msgid "None" +msgstr "無" + +#: src/libaudgui/prefs-window.cc:119 src/libaudqt/prefs-window-qt.cc:181 +msgid "Arabic" +msgstr "阿拉伯語" + +#: src/libaudgui/prefs-window.cc:120 src/libaudqt/prefs-window-qt.cc:182 +msgid "Baltic" +msgstr "波羅的海" + +#: src/libaudgui/prefs-window.cc:121 src/libaudqt/prefs-window-qt.cc:183 +msgid "Chinese" +msgstr "中文" + +#: src/libaudgui/prefs-window.cc:122 src/libaudqt/prefs-window-qt.cc:184 +msgid "Greek" +msgstr "希臘語" + +#: src/libaudgui/prefs-window.cc:123 src/libaudqt/prefs-window-qt.cc:185 +msgid "Hebrew" +msgstr "希伯來語" + +#: src/libaudgui/prefs-window.cc:124 src/libaudqt/prefs-window-qt.cc:186 +msgid "Japanese" +msgstr "日本語" + +#: src/libaudgui/prefs-window.cc:125 src/libaudqt/prefs-window-qt.cc:187 +msgid "Korean" +msgstr "韓文" + +#: src/libaudgui/prefs-window.cc:126 src/libaudqt/prefs-window-qt.cc:188 +msgid "Polish" +msgstr "波蘭語" + +#: src/libaudgui/prefs-window.cc:127 src/libaudqt/prefs-window-qt.cc:189 +msgid "Russian" +msgstr "俄語" + +#: src/libaudgui/prefs-window.cc:128 src/libaudqt/prefs-window-qt.cc:190 +msgid "Taiwanese" +msgstr "正體中文" + +#: src/libaudgui/prefs-window.cc:129 src/libaudqt/prefs-window-qt.cc:191 +msgid "Turkish" +msgstr "土耳其語" + +#: src/libaudgui/prefs-window.cc:133 src/libaudqt/prefs-window-qt.cc:194 +msgid "Automatic" +msgstr "自動" + +#: src/libaudgui/prefs-window.cc:137 src/libaudqt/prefs-window-qt.cc:195 +msgid "Floating point" +msgstr "浮點數" + +#: src/libaudgui/prefs-window.cc:141 src/libaudqt/prefs-window-qt.cc:198 +msgid "As decoded" +msgstr "解碼後立即擷取" + +#: src/libaudgui/prefs-window.cc:142 src/libaudqt/prefs-window-qt.cc:199 +msgid "After applying ReplayGain" +msgstr "套用播放增益後擷取" + +#: src/libaudgui/prefs-window.cc:143 src/libaudqt/prefs-window-qt.cc:201 +msgid "After applying effects" +msgstr "套用特效後擷取" + +#: src/libaudgui/prefs-window.cc:144 src/libaudqt/prefs-window-qt.cc:202 +msgid "After applying equalization" +msgstr "套用等化器效果後擷取" + +#: src/libaudgui/prefs-window.cc:150 src/libaudqt/prefs-window-qt.cc:208 +msgid "Based on shuffle" +msgstr "基於隨機排序" + +#: src/libaudgui/prefs-window.cc:162 src/libaudqt/prefs-window-qt.cc:219 +msgid "Interface:" +msgstr "介面:" + +#: src/libaudgui/prefs-window.cc:181 src/libaudqt/prefs-window-qt.cc:227 +msgid "Output plugin:" +msgstr "輸出外掛:" + +#: src/libaudgui/prefs-window.cc:202 src/libaudqt/prefs-window-qt.cc:240 +msgid "Amplify all files:" +msgstr "放大所有檔案的音量:" + +#: src/libaudgui/prefs-window.cc:204 src/libaudgui/prefs-window.cc:207 +#: src/libaudqt/prefs-window-qt.cc:241 src/libaudqt/prefs-window-qt.cc:243 +msgid "dB" +msgstr "分貝" + +#: src/libaudgui/prefs-window.cc:205 src/libaudqt/prefs-window-qt.cc:242 +msgid "Amplify untagged files:" +msgstr "放大無標籤檔案的音量:" + +#: src/libaudgui/prefs-window.cc:211 src/libaudqt/prefs-window-qt.cc:246 +msgid "Output Settings" +msgstr "輸出設定" + +#: src/libaudgui/prefs-window.cc:213 src/libaudqt/prefs-window-qt.cc:248 +msgid "Bit depth:" +msgstr "取樣格式:" + +#: src/libaudgui/prefs-window.cc:216 src/libaudgui/prefs-window.cc:261 +#: src/libaudqt/prefs-window-qt.cc:251 src/libaudqt/prefs-window-qt.cc:279 +msgid "Buffer size:" +msgstr "緩衝區大小:" + +#: src/libaudgui/prefs-window.cc:218 src/libaudqt/prefs-window-qt.cc:252 +msgid "ms" +msgstr "毫秒" + +#: src/libaudgui/prefs-window.cc:219 src/libaudqt/prefs-window-qt.cc:253 +msgid "Soft clipping" +msgstr "軟性削峰" + +#: src/libaudgui/prefs-window.cc:221 src/libaudqt/prefs-window-qt.cc:254 +msgid "Use software volume control (not recommended)" +msgstr "使用軟體音量控制 (不建議開啟)" + +#: src/libaudgui/prefs-window.cc:223 src/libaudqt/prefs-window-qt.cc:256 +msgid "Recording Settings" +msgstr "錄音設定" + +#: src/libaudgui/prefs-window.cc:227 src/libaudqt/prefs-window-qt.cc:259 +msgid "Record stream:" +msgstr "錄音資料流來源:" + +#: src/libaudgui/prefs-window.cc:230 src/libaudqt/prefs-window-qt.cc:261 +msgid "ReplayGain" +msgstr "播放增益" + +#: src/libaudgui/prefs-window.cc:231 src/libaudqt/prefs-window-qt.cc:262 +msgid "Enable ReplayGain" +msgstr "啟用播放增益" + +#: src/libaudgui/prefs-window.cc:233 src/libaudqt/prefs-window-qt.cc:263 +msgid "Mode:" +msgstr "模式:" + +#: src/libaudgui/prefs-window.cc:237 src/libaudqt/prefs-window-qt.cc:265 +msgid "Prevent clipping (recommended)" +msgstr "防止訊號裁剪 (建議開啟)" + +#: src/libaudgui/prefs-window.cc:245 src/libaudqt/prefs-window-qt.cc:270 +msgid "Proxy hostname:" +msgstr "代理伺服器名稱:" + +#: src/libaudgui/prefs-window.cc:247 src/libaudqt/prefs-window-qt.cc:271 +msgid "Proxy port:" +msgstr "代理伺服器連接埠:" + +#: src/libaudgui/prefs-window.cc:252 src/libaudqt/prefs-window-qt.cc:274 +msgid "Proxy username:" +msgstr "代理伺服器使用者名稱:" + +#: src/libaudgui/prefs-window.cc:254 src/libaudqt/prefs-window-qt.cc:275 +msgid "Proxy password:" +msgstr "代理伺服器密碼:" + +#: src/libaudgui/prefs-window.cc:260 src/libaudqt/prefs-window-qt.cc:278 +msgid "Network Settings" +msgstr "網路設定" + +#: src/libaudgui/prefs-window.cc:263 src/libaudqt/prefs-window-qt.cc:280 +msgid "KiB" +msgstr "KiB" + +#: src/libaudgui/prefs-window.cc:264 src/libaudqt/prefs-window-qt.cc:281 +msgid "Proxy Configuration" +msgstr "代理伺服器設定" + +#: src/libaudgui/prefs-window.cc:265 src/libaudqt/prefs-window-qt.cc:282 +msgid "Enable proxy usage" +msgstr "啟用代理伺服器" + +#: src/libaudgui/prefs-window.cc:269 src/libaudqt/prefs-window-qt.cc:284 +msgid "Use authentication with proxy" +msgstr "需要認證" + +#: src/libaudgui/prefs-window.cc:273 src/libaudqt/prefs-window-qt.cc:287 +msgid "Use SOCKS proxy" +msgstr "使用 SOCKS 代理伺服器" + +#: src/libaudgui/prefs-window.cc:275 src/libaudqt/prefs-window-qt.cc:288 +msgid "SOCKS v4a" +msgstr "SOCKS v4a" + +#: src/libaudgui/prefs-window.cc:279 src/libaudqt/prefs-window-qt.cc:289 +msgid "SOCKS v5" +msgstr "SOCKS v5" + +#: src/libaudgui/prefs-window.cc:286 src/libaudqt/prefs-window-qt.cc:292 +msgid "Auto character encoding detector for:" +msgstr "自動偵測字元編碼:" + +#: src/libaudgui/prefs-window.cc:289 src/libaudqt/prefs-window-qt.cc:295 +msgid "Fallback character encodings:" +msgstr "備用字元編碼:" + +#: src/libaudgui/prefs-window.cc:297 src/libaudqt/prefs-window-qt.cc:302 +msgid "Behavior" +msgstr "行為" + +#: src/libaudgui/prefs-window.cc:298 src/libaudqt/prefs-window-qt.cc:303 +msgid "Resume playback on startup" +msgstr "啟動時回復之前的播放狀態" + +#: src/libaudgui/prefs-window.cc:300 src/libaudqt/prefs-window-qt.cc:305 +msgid "Pause instead of resuming immediately" +msgstr "暫停而非立刻回復播放" + +#: src/libaudgui/prefs-window.cc:303 src/libaudqt/prefs-window-qt.cc:307 +msgid "Advance when the current song is deleted" +msgstr "目前的歌曲被刪除時移到下一個項目" + +#: src/libaudgui/prefs-window.cc:305 src/libaudqt/prefs-window-qt.cc:309 +msgid "Clear the playlist when opening files" +msgstr "開啟檔案後清除播放清單" + +#: src/libaudgui/prefs-window.cc:307 src/libaudqt/prefs-window-qt.cc:311 +msgid "Open files in a temporary playlist" +msgstr "在暫存播放清單中開啟檔案" + +#: src/libaudgui/prefs-window.cc:309 src/libaudqt/prefs-window-qt.cc:313 +msgid "Song Display" +msgstr "顯示歌曲" + +#: src/libaudgui/prefs-window.cc:310 src/libaudqt/prefs-window-qt.cc:314 +msgid "Show song numbers" +msgstr "顯示歌曲編號" + +#: src/libaudgui/prefs-window.cc:312 src/libaudqt/prefs-window-qt.cc:316 +msgid "Show leading zeroes (02:00 vs. 2:00)" +msgstr "顯示開頭的數字零 (02:00 vs. 2:00)" + +#: src/libaudgui/prefs-window.cc:314 src/libaudqt/prefs-window-qt.cc:318 +msgid "Show hours separately (1:30:00 vs. 90:00)" +msgstr "將小時分開顯示 (1:30:00 vs. 90:00)" + +#: src/libaudgui/prefs-window.cc:317 src/libaudqt/prefs-window-qt.cc:321 +msgid "Export" +msgstr "匯出" + +#: src/libaudgui/prefs-window.cc:318 src/libaudqt/prefs-window-qt.cc:322 +msgid "Use relative paths when possible" +msgstr "盡可能地使用相對路徑" + +#: src/libaudgui/prefs-window.cc:323 src/libaudqt/prefs-window-qt.cc:326 +msgid "Album Art" +msgstr "專輯封面" + +#: src/libaudgui/prefs-window.cc:324 src/libaudqt/prefs-window-qt.cc:328 +msgid "Search for images matching these words (comma-separated):" +msgstr "搜尋符合這些單字的圖片 (以逗號分隔):" + +#: src/libaudgui/prefs-window.cc:326 src/libaudqt/prefs-window-qt.cc:330 +msgid "Exclude images matching these words (comma-separated):" +msgstr "排除符合這些單字的圖片 (以逗號分隔):" + +#: src/libaudgui/prefs-window.cc:328 src/libaudqt/prefs-window-qt.cc:332 +msgid "Search for images matching song file name" +msgstr "搜尋符合歌曲檔名的圖片" + +#: src/libaudgui/prefs-window.cc:330 src/libaudqt/prefs-window-qt.cc:334 +msgid "Search recursively" +msgstr "遞迴搜尋" + +#: src/libaudgui/prefs-window.cc:332 src/libaudqt/prefs-window-qt.cc:335 +msgid "Search depth:" +msgstr "搜尋深度:" + +#: src/libaudgui/prefs-window.cc:336 src/libaudqt/prefs-window-qt.cc:337 +msgid "Popup Information" +msgstr "彈出式資訊視窗" + +#: src/libaudgui/prefs-window.cc:337 src/libaudqt/prefs-window-qt.cc:338 +msgid "Show popup information" +msgstr "顯示彈出式資訊視窗" + +#: src/libaudgui/prefs-window.cc:339 src/libaudqt/prefs-window-qt.cc:340 +msgid "Popup delay (tenths of a second):" +msgstr "彈出視窗的延遲時間 (十分之一秒):" + +#: src/libaudgui/prefs-window.cc:343 src/libaudqt/prefs-window-qt.cc:342 +msgid "Show time scale for current song" +msgstr "顯示目前歌曲的時間軸" + +#: src/libaudgui/prefs-window.cc:349 src/libaudqt/prefs-window-qt.cc:346 +msgid "Compatibility" +msgstr "相容性" + +#: src/libaudgui/prefs-window.cc:350 src/libaudqt/prefs-window-qt.cc:347 +msgid "Interpret \\ (backward slash) as a folder delimiter" +msgstr "將 \\ (反斜線) 視為資料夾分隔符號" + +#: src/libaudgui/prefs-window.cc:353 src/libaudqt/prefs-window-qt.cc:350 +msgid "Playlist" +msgstr "播放清單" + +#: src/libaudgui/prefs-window.cc:354 src/libaudqt/prefs-window-qt.cc:351 +msgid "Add folders recursively" +msgstr "遞迴新增資料夾" + +#: src/libaudgui/prefs-window.cc:356 src/libaudqt/prefs-window-qt.cc:353 +msgid "Add folders nested within playlist files" +msgstr "" + +#: src/libaudgui/prefs-window.cc:358 src/libaudqt/prefs-window-qt.cc:355 +msgid "Metadata" +msgstr "詮釋資料" + +#: src/libaudgui/prefs-window.cc:359 src/libaudqt/prefs-window-qt.cc:356 +msgid "Guess missing metadata from file path" +msgstr "依據檔案路徑補上欠缺的詮釋資料" + +#: src/libaudgui/prefs-window.cc:361 src/libaudqt/prefs-window-qt.cc:358 +msgid "Do not load metadata for songs until played" +msgstr "在歌曲播放以前不要載入詮釋資料" + +#: src/libaudgui/prefs-window.cc:363 src/libaudqt/prefs-window-qt.cc:361 +msgid "Probe content of files with no recognized file name extension" +msgstr "偵測帶有不明副檔名的檔案內容" + +#: src/libaudgui/prefs-window.cc:365 src/libaudqt/prefs-window-qt.cc:363 +msgid "Miscellaneous" +msgstr "其他選項" + +#: src/libaudgui/prefs-window.cc:366 src/libaudqt/prefs-window-qt.cc:364 +msgid "Step forward/backward by:" +msgstr "每次跳轉的時間長為:" + +#: src/libaudgui/prefs-window.cc:368 src/libaudqt/prefs-window-qt.cc:365 +msgid "seconds" +msgstr "秒" + +#: src/libaudgui/prefs-window.cc:369 src/libaudqt/prefs-window-qt.cc:366 +msgid "Adjust volume by:" +msgstr "每次調整音量:" + +#: src/libaudgui/prefs-window.cc:371 src/libaudqt/prefs-window-qt.cc:367 +msgid "percent" +msgstr "%" + +#: src/libaudgui/prefs-window.cc:388 src/libaudqt/prefs-window-qt.cc:384 +msgid "TITLE" +msgstr "標題" + +#: src/libaudgui/prefs-window.cc:389 src/libaudqt/prefs-window-qt.cc:385 +msgid "TITLE - ARTIST" +msgstr "標題 - 藝人" + +#: src/libaudgui/prefs-window.cc:390 src/libaudqt/prefs-window-qt.cc:386 +msgid "TITLE - ARTIST - ALBUM" +msgstr "標題 - 藝人 - 專輯" + +#: src/libaudgui/prefs-window.cc:391 src/libaudqt/prefs-window-qt.cc:387 +msgid "ARTIST - TITLE" +msgstr "藝人 - 標題" + +#: src/libaudgui/prefs-window.cc:392 src/libaudqt/prefs-window-qt.cc:388 +msgid "ARTIST - ALBUM - TITLE" +msgstr "藝人 - 專輯 - 標題" + +#: src/libaudgui/prefs-window.cc:393 src/libaudqt/prefs-window-qt.cc:389 +msgid "ARTIST - ALBUM - TRACK. TITLE" +msgstr "藝人 - 專輯 - 音軌. 標題" + +#: src/libaudgui/prefs-window.cc:394 src/libaudqt/prefs-window-qt.cc:390 +msgid "ARTIST [ ALBUM ] - TRACK. TITLE" +msgstr "藝人 [ 專輯 ] - 音軌. 標題" + +#: src/libaudgui/prefs-window.cc:395 src/libaudqt/prefs-window-qt.cc:391 +msgid "ALBUM - TITLE" +msgstr "專輯 - 標題" + +#: src/libaudgui/prefs-window.cc:489 +msgid "Category" +msgstr "目錄" + +#: src/libaudgui/prefs-window.cc:553 src/libaudqt/prefs-window-qt.cc:408 +msgid "Custom" +msgstr "自訂" + +#: src/libaudgui/prefs-window.cc:571 src/libaudqt/prefs-window-qt.cc:400 +msgid "Title format:" +msgstr "標題格式:" + +#: src/libaudgui/prefs-window.cc:575 src/libaudqt/prefs-window-qt.cc:411 +msgid "Custom string:" +msgstr "自訂字串:" + +#: src/libaudgui/prefs-window.cc:774 src/libaudqt/prefs-window-qt.cc:705 +#, c-format +msgid "Enable audio stream recording with %s" +msgstr "啟用%s進行音訊串流錄製" + +#: src/libaudgui/prefs-window.cc:783 src/libaudqt/prefs-window-qt.cc:718 +msgid "No audio recording plugin available" +msgstr "找不到可用的錄音外掛" + +#: src/libaudgui/prefs-window.cc:843 src/libaudqt/prefs-window-qt.cc:593 +msgid "Audacious Settings" +msgstr "Audacious 設定" + +#: src/libaudgui/preset-browser.cc:53 src/libaudgui/util.cc:172 +msgid "Cancel" +msgstr "取消" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:290 +msgid "Save" +msgstr "儲存" + +#: src/libaudgui/preset-browser.cc:54 src/libaudqt/eq-preset-qt.cc:257 +msgid "Load" +msgstr "載入" + +#: src/libaudgui/preset-browser.cc:85 src/libaudqt/eq-preset-qt.cc:253 +msgid "Load Preset File" +msgstr "載入預設集檔案" + +#: src/libaudgui/preset-browser.cc:99 +msgid "Load EQF File" +msgstr "載入 EQF 檔案" + +#: src/libaudgui/preset-browser.cc:114 src/libaudqt/eq-preset-qt.cc:285 +msgid "Save Preset File" +msgstr "儲存預設集到檔案" + +#: src/libaudgui/preset-browser.cc:131 +msgid "Save EQF File" +msgstr "儲存 EQF 檔" + +#: src/libaudgui/queue-manager.cc:175 src/libaudqt/queue-manager-qt.cc:158 +msgid "Queue Manager" +msgstr "佇列管理" + +#: src/libaudgui/queue-manager.cc:193 src/libaudqt/queue-manager-qt.cc:161 +msgid "_Unqueue" +msgstr "移出佇列(_U)" + +#: src/libaudgui/status.cc:36 +msgid "Working ..." +msgstr "處理中 ..." + +#: src/libaudgui/status.cc:85 src/libaudqt/log-inspector.cc:223 +msgid "Error" +msgstr "錯誤" + +#: src/libaudgui/status.cc:90 +msgid "Information" +msgstr "資訊" + +#: src/libaudgui/url-opener.cc:55 src/libaudqt/url-opener-qt.cc:40 +msgid "_Save to history" +msgstr "儲存到歷史紀錄(_S)" + +#: src/libaudgui/url-opener.cc:63 src/libaudqt/url-opener-qt.cc:46 +msgid "Open URL" +msgstr "開啟網址" + +#: src/libaudgui/url-opener.cc:69 src/libaudqt/url-opener-qt.cc:52 +msgid "Add URL" +msgstr "加入網址" + +#: src/libaudgui/url-opener.cc:92 src/libaudqt/url-opener-qt.cc:68 +msgid "C_lear history" +msgstr "清除歷史紀錄(_L)" + +#: src/libaudgui/url-opener.cc:104 src/libaudqt/url-opener-qt.cc:61 +msgid "Enter URL:" +msgstr "請輸入網址:" + +#: src/libaudgui/util.cc:172 src/libaudqt/fileopener.cc:62 +msgid "Open" +msgstr "開啟" + +#: src/libaudgui/util.cc:283 +msgid "" +"\n" +"(Further messages have been hidden.)" +msgstr "\n(詳細訊息已被隱藏。)" + +#: src/libaudqt/eq-preset-qt.cc:249 +msgid "Preset files (*.preset *.eqf *.q1)" +msgstr "" + +#: src/libaudqt/eq-preset-qt.cc:348 +msgid "Close" +msgstr "關閉" + +#: src/libaudqt/file-entry.cc:40 +msgid "Browse" +msgstr "瀏覽" + +#: src/libaudqt/fileopener.cc:58 +msgid "Open Folder" +msgstr "開啟資料夾" + +#: src/libaudqt/fileopener.cc:59 +msgid "Add Folder" +msgstr "加入資料夾" + +#: src/libaudqt/fileopener.cc:62 src/libaudqt/fileopener.cc:63 +msgid "Add" +msgstr "加入" + +#: src/libaudqt/font-entry.cc:39 +msgid "Set Font" +msgstr "設定字型" + +#: src/libaudqt/info-widget.cc:44 +msgid "" +msgstr "" + +#: src/libaudqt/info-widget.cc:47 +msgid "Metadata" +msgstr "詮釋資料" + +#: src/libaudqt/info-widget.cc:56 +msgid "Composer" +msgstr "作曲" + +#: src/libaudqt/info-widget.cc:57 +msgid "Performer" +msgstr "表演者" + +#: src/libaudqt/info-widget.cc:58 +msgid "Recording Year" +msgstr "錄製年份" + +#: src/libaudqt/info-widget.cc:59 +msgid "Recording Date" +msgstr "錄製日期" + +#: src/libaudqt/info-widget.cc:62 +msgid "Technical" +msgstr "技術性資訊" + +#: src/libaudqt/info-widget.cc:66 +msgid "Bitrate" +msgstr "位元率" + +#: src/libaudqt/info-widget.cc:67 +msgid "MusicBrainz ID" +msgstr "MusicBrainz ID" + +#: src/libaudqt/infowin-qt.cc:156 +msgid "_Revert" +msgstr "" + +#: src/libaudqt/infowin-qt.cc:167 +msgid "Error writing tag(s)." +msgstr "寫入標籤時發生錯誤。" + +#: src/libaudqt/infowin-qt.cc:189 +msgid "%1 files selected" +msgstr "選擇了 %1 個檔案" + +#: src/libaudqt/infowin-qt.cc:193 +msgid "_Save %1 files" +msgstr "儲存 %1 個檔案(_S)" + +#: src/libaudqt/log-inspector.cc:150 +msgid "Level" +msgstr "等級" + +#: src/libaudqt/log-inspector.cc:152 +msgid "Function" +msgstr "功能" + +#: src/libaudqt/log-inspector.cc:154 +msgid "Message" +msgstr "訊息" + +#: src/libaudqt/log-inspector.cc:209 +msgid "Log Inspector" +msgstr "記錄監控" + +#: src/libaudqt/log-inspector.cc:220 +msgid "Debug" +msgstr "除錯" + +#: src/libaudqt/log-inspector.cc:221 +msgid "Info" +msgstr "資訊" + +#: src/libaudqt/log-inspector.cc:222 +msgid "Warning" +msgstr "警告" + +#: src/libaudqt/log-inspector.cc:234 +msgid "Cl_ear" +msgstr "清除(_E)" + +#: src/libaudqt/log-inspector.cc:247 +msgid "Log Level:" +msgstr "記錄等級:" + +#: src/libaudqt/plugin-menu-qt.cc:52 +msgid "Services" +msgstr "服務" + +#: src/libaudqt/util-qt.cc:112 +msgid "Copy" +msgstr "複製" diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..bb63ed4 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,33 @@ +include ../extra.mk + +SUBDIRS := audacious libaudcore libaudtag libguess + +ifeq ($(USE_GTK),yes) +SUBDIRS += libaudgui +endif + +ifeq ($(USE_QT),yes) +SUBDIRS += libaudqt +endif + +ifeq ($(USE_DBUS),yes) +SUBDIRS := dbus audtool ${SUBDIRS} +endif + +include ../buildsys.mk + +audacious: libaudcore +libaudcore: libguess +libaudtag: libaudcore + +ifeq ($(USE_GTK),yes) +libaudgui: libaudcore +endif + +ifeq ($(USE_QT),yes) +libaudqt: libaudcore +endif + +ifeq ($(USE_DBUS),yes) +audacious audtool: dbus +endif diff --git a/src/audacious/Makefile b/src/audacious/Makefile new file mode 100644 index 0000000..79e86cd --- /dev/null +++ b/src/audacious/Makefile @@ -0,0 +1,40 @@ +include ../../extra.mk + +PROG = audacious${PROG_SUFFIX} + +SRCS = main.cc \ + signals.cc \ + util.cc + +ifeq ($(HAVE_MSWINDOWS),yes) +SRCS += audacious.rc +endif + +ifeq ($(USE_DBUS),yes) +SRCS += dbus-server.cc +EXT_DEPS += ../dbus/aud-dbus.a +endif + +include ../../buildsys.mk + +ifeq ($(USE_DBUS),yes) +CPPFLAGS := -I../dbus ${CPPFLAGS} ${GIO_CFLAGS} +LIBS := ../dbus/aud-dbus.a ${LIBS} ${GIO_LIBS} +endif + +LD = ${CXX} + +CPPFLAGS := -I.. -I../.. \ + ${CPPFLAGS} \ + ${GLIB_CFLAGS} + +LDFLAGS := -L../libaudcore $(LDFLAGS) + +LIBS := -laudcore \ + ${LIBS} -lm \ + ${LIBINTL} \ + ${GLIB_LIBS} + +ifeq ($(HAVE_MSWINDOWS),yes) +LDFLAGS := ${LDFLAGS} -Wl,-subsystem,windows +endif diff --git a/src/audacious/audacious.manifest b/src/audacious/audacious.manifest new file mode 100644 index 0000000..1fc9cfd --- /dev/null +++ b/src/audacious/audacious.manifest @@ -0,0 +1,8 @@ + + + + + true + + + diff --git a/src/audacious/audacious.rc b/src/audacious/audacious.rc new file mode 100644 index 0000000..89c09e3 --- /dev/null +++ b/src/audacious/audacious.rc @@ -0,0 +1,7 @@ +#include + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "audacious.manifest" + +100 ICON "../../images/audacious.ico" diff --git a/src/audacious/dbus-server.cc b/src/audacious/dbus-server.cc new file mode 100644 index 0000000..10f3bba --- /dev/null +++ b/src/audacious/dbus-server.cc @@ -0,0 +1,951 @@ +/* + * dbus-server.c + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "aud-dbus.h" +#include "main.h" + +typedef ObjAudacious Obj; +typedef GDBusMethodInvocation Invoc; + +#define FINISH(name) \ + obj_audacious_complete_##name (obj, invoc) + +#define FINISH2(name, ...) \ + obj_audacious_complete_##name (obj, invoc, __VA_ARGS__) + +static bool prefer_playing = true; + +static Playlist current_playlist () +{ + Playlist list; + + if (prefer_playing) + list = Playlist::playing_playlist (); + if (list == Playlist ()) + list = Playlist::active_playlist (); + + return list; +} + +#define CURRENT current_playlist () + +static Index strv_to_index (const char * const * strv) +{ + Index index; + while (* strv) + index.append (String (* strv ++)); + + return index; +} + +static gboolean do_add (Obj * obj, Invoc * invoc, const char * file) +{ + CURRENT.insert_entry (-1, file, Tuple (), false); + FINISH (add); + return true; +} + +static gboolean do_add_list (Obj * obj, Invoc * invoc, const char * const * filenames) +{ + CURRENT.insert_items (-1, strv_to_index (filenames), false); + FINISH (add_list); + return true; +} + +static gboolean do_add_url (Obj * obj, Invoc * invoc, const char * url) +{ + CURRENT.insert_entry (-1, url, Tuple (), false); + FINISH (add_url); + return true; +} + +static gboolean do_advance (Obj * obj, Invoc * invoc) +{ + CURRENT.next_song (aud_get_bool ("repeat")); + FINISH (advance); + return true; +} + +static gboolean do_advance_album (Obj * obj, Invoc * invoc) +{ + CURRENT.next_album (aud_get_bool ("repeat")); + FINISH (advance_album); + return true; +} + +static gboolean do_auto_advance (Obj * obj, Invoc * invoc) +{ + FINISH2 (auto_advance, ! aud_get_bool ("no_playlist_advance")); + return true; +} + +static gboolean do_balance (Obj * obj, Invoc * invoc) +{ + FINISH2 (balance, aud_drct_get_volume_balance ()); + return true; +} + +static gboolean do_clear (Obj * obj, Invoc * invoc) +{ + CURRENT.remove_all_entries (); + FINISH (clear); + return true; +} + +static gboolean do_config_get (Obj * obj, Invoc * invoc, const char * section, const char * name) +{ + String value = aud_get_str (section[0] ? section : nullptr, name); + FINISH2 (config_get, value); + return true; +} + +static gboolean do_config_set (Obj * obj, Invoc * invoc, const char * section, + const char * name, const char * value) +{ + aud_set_str (section[0] ? section : nullptr, name, value); + FINISH (config_set); + return true; +} + +static gboolean do_delete (Obj * obj, Invoc * invoc, unsigned pos) +{ + CURRENT.remove_entry (pos); + FINISH (delete); + return true; +} + +static gboolean do_delete_active_playlist (Obj * obj, Invoc * invoc) +{ + CURRENT.remove_playlist (); + FINISH (delete_active_playlist); + return true; +} + +static gboolean do_eject (Obj * obj, Invoc * invoc) +{ + if (! aud_get_headless_mode ()) + aud_ui_show_filebrowser (true); + + FINISH (eject); + return true; +} + +static gboolean do_equalizer_activate (Obj * obj, Invoc * invoc, gboolean active) +{ + aud_set_bool ("equalizer_active", active); + FINISH (equalizer_activate); + return true; +} + +static gboolean do_get_active_playlist (Obj * obj, Invoc * invoc) +{ + FINISH2 (get_active_playlist, CURRENT.index ()); + return true; +} + +static gboolean do_get_active_playlist_name (Obj * obj, Invoc * invoc) +{ + String title = CURRENT.get_title (); + FINISH2 (get_active_playlist_name, title ? title : ""); + return true; +} + +static gboolean do_get_eq (Obj * obj, Invoc * invoc) +{ + double preamp = aud_get_double ("equalizer_preamp"); + double bands[AUD_EQ_NBANDS]; + aud_eq_get_bands (bands); + + GVariant * var = g_variant_new_fixed_array (G_VARIANT_TYPE_DOUBLE, bands, + AUD_EQ_NBANDS, sizeof (double)); + FINISH2 (get_eq, preamp, var); + return true; +} + +static gboolean do_get_eq_band (Obj * obj, Invoc * invoc, int band) +{ + FINISH2 (get_eq_band, aud_eq_get_band (band)); + return true; +} + +static gboolean do_get_eq_preamp (Obj * obj, Invoc * invoc) +{ + FINISH2 (get_eq_preamp, aud_get_double ("equalizer_preamp")); + return true; +} + +static gboolean do_get_info (Obj * obj, Invoc * invoc) +{ + int bitrate, samplerate, channels; + aud_drct_get_info (bitrate, samplerate, channels); + FINISH2 (get_info, bitrate, samplerate, channels); + return true; +} + +static gboolean do_get_playqueue_length (Obj * obj, Invoc * invoc) +{ + FINISH2 (get_playqueue_length, CURRENT.n_queued ()); + return true; +} + +static gboolean do_get_tuple_fields (Obj * obj, Invoc * invoc) +{ + const char * fields[Tuple::n_fields + 1]; + + for (auto f : Tuple::all_fields ()) + fields[f] = Tuple::field_get_name (f); + + fields[Tuple::n_fields] = nullptr; + + FINISH2 (get_tuple_fields, fields); + return true; +} + +static gboolean do_info (Obj * obj, Invoc * invoc) +{ + int bitrate, samplerate, channels; + aud_drct_get_info (bitrate, samplerate, channels); + FINISH2 (info, bitrate, samplerate, channels); + return true; +} + +static gboolean do_jump (Obj * obj, Invoc * invoc, unsigned pos) +{ + CURRENT.set_position (pos); + FINISH (jump); + return true; +} + +static gboolean do_length (Obj * obj, Invoc * invoc) +{ + FINISH2 (length, CURRENT.n_entries ()); + return true; +} + +static gboolean do_main_win_visible (Obj * obj, Invoc * invoc) +{ + FINISH2 (main_win_visible, ! aud_get_headless_mode () && aud_ui_is_shown ()); + return true; +} + +static gboolean do_new_playlist (Obj * obj, Invoc * invoc) +{ + Playlist::insert_playlist (CURRENT.index () + 1).activate (); + aud_drct_stop (); + FINISH (new_playlist); + return true; +} + +static gboolean do_number_of_playlists (Obj * obj, Invoc * invoc) +{ + FINISH2 (number_of_playlists, Playlist::n_playlists ()); + return true; +} + +static gboolean do_open_list (Obj * obj, Invoc * invoc, const char * const * filenames) +{ + aud_drct_pl_open_list (strv_to_index (filenames)); + FINISH (open_list); + return true; +} + +static gboolean do_open_list_to_temp (Obj * obj, Invoc * invoc, const char * const * filenames) +{ + aud_drct_pl_open_temp_list (strv_to_index (filenames)); + FINISH (open_list_to_temp); + return true; +} + +static gboolean do_pause (Obj * obj, Invoc * invoc) +{ + aud_drct_pause (); + FINISH (pause); + return true; +} + +static gboolean do_paused (Obj * obj, Invoc * invoc) +{ + FINISH2 (paused, aud_drct_get_paused ()); + return true; +} + +static gboolean do_play (Obj * obj, Invoc * invoc) +{ + aud_drct_play (); + FINISH (play); + return true; +} + +static gboolean do_play_active_playlist (Obj * obj, Invoc * invoc) +{ + CURRENT.start_playback (); + FINISH (play_active_playlist); + return true; +} + +static gboolean do_play_pause (Obj * obj, Invoc * invoc) +{ + aud_drct_play_pause (); + FINISH (play_pause); + return true; +} + +static gboolean do_playing (Obj * obj, Invoc * invoc) +{ + FINISH2 (playing, aud_drct_get_playing ()); + return true; +} + +static gboolean do_playlist_add (Obj * obj, Invoc * invoc, const char * list) +{ + CURRENT.insert_entry (-1, list, Tuple (), false); + FINISH (playlist_add); + return true; +} + +static gboolean do_playlist_enqueue_to_temp (Obj * obj, Invoc * invoc, const char * url) +{ + aud_drct_pl_open_temp (url); + FINISH (playlist_enqueue_to_temp); + return true; +} + +static gboolean do_playlist_ins_url_string (Obj * obj, Invoc * invoc, const char * url, int pos) +{ + CURRENT.insert_entry (pos, url, Tuple (), false); + FINISH (playlist_ins_url_string); + return true; +} + +static gboolean do_playqueue_add (Obj * obj, Invoc * invoc, int pos) +{ + CURRENT.queue_insert (-1, pos); + FINISH (playqueue_add); + return true; +} + +static gboolean do_playqueue_clear (Obj * obj, Invoc * invoc) +{ + CURRENT.queue_remove_all (); + FINISH (playqueue_clear); + return true; +} + +static gboolean do_playqueue_is_queued (Obj * obj, Invoc * invoc, int pos) +{ + bool queued = (CURRENT.queue_find_entry (pos) >= 0); + FINISH2 (playqueue_is_queued, queued); + return true; +} + +static gboolean do_playqueue_remove (Obj * obj, Invoc * invoc, int pos) +{ + auto playlist = CURRENT; + int qpos = playlist.queue_find_entry (pos); + + if (qpos >= 0) + playlist.queue_remove (qpos); + + FINISH (playqueue_remove); + return true; +} + +static gboolean do_plugin_enable (Obj * obj, Invoc * invoc, const char * name, gboolean enable) +{ + PluginHandle * plugin = aud_plugin_lookup_basename (name); + if (! plugin) + { + AUDERR ("No such plugin: %s\n", name); + return false; + } + + aud_plugin_enable (plugin, enable); + FINISH (plugin_enable); + return true; +} + +static gboolean do_plugin_is_enabled (Obj * obj, Invoc * invoc, const char * name) +{ + PluginHandle * plugin = aud_plugin_lookup_basename (name); + if (! plugin) + { + AUDERR ("No such plugin: %s\n", name); + return false; + } + + FINISH2 (plugin_is_enabled, aud_plugin_get_enabled (plugin)); + return true; +} + +static gboolean do_position (Obj * obj, Invoc * invoc) +{ + FINISH2 (position, CURRENT.get_position ()); + return true; +} + +static gboolean do_queue_get_list_pos (Obj * obj, Invoc * invoc, unsigned qpos) +{ + FINISH2 (queue_get_list_pos, CURRENT.queue_get_entry (qpos)); + return true; +} + +static gboolean do_queue_get_queue_pos (Obj * obj, Invoc * invoc, unsigned pos) +{ + FINISH2 (queue_get_queue_pos, CURRENT.queue_find_entry (pos)); + return true; +} + +static gboolean do_quit (Obj * obj, Invoc * invoc) +{ + aud_quit (); + FINISH (quit); + return true; +} + +static gboolean do_record (Obj * obj, Invoc * invoc) +{ + if (aud_drct_get_record_enabled ()) + aud_set_bool ("record", ! aud_get_bool ("record")); + + FINISH (record); + return true; +} + +static gboolean do_recording (Obj * obj, Invoc * invoc) +{ + bool recording = false; + if (aud_drct_get_record_enabled ()) + recording = aud_get_bool ("record"); + + FINISH2 (recording, recording); + return true; +} + +static gboolean do_repeat (Obj * obj, Invoc * invoc) +{ + FINISH2 (repeat, aud_get_bool ("repeat")); + return true; +} + +static gboolean do_reverse (Obj * obj, Invoc * invoc) +{ + CURRENT.prev_song (); + FINISH (reverse); + return true; +} + +static gboolean do_reverse_album (Obj * obj, Invoc * invoc) +{ + CURRENT.prev_album (); + FINISH (reverse_album); + return true; +} + +static gboolean do_seek (Obj * obj, Invoc * invoc, unsigned pos) +{ + aud_drct_seek (pos); + FINISH (seek); + return true; +} + +static gboolean do_select_displayed_playlist (Obj * obj, Invoc * invoc) +{ + prefer_playing = false; + FINISH (select_displayed_playlist); + return true; +} + +static gboolean do_select_playing_playlist (Obj * obj, Invoc * invoc) +{ + prefer_playing = true; + FINISH (select_playing_playlist); + return true; +} + +static gboolean do_set_active_playlist (Obj * obj, Invoc * invoc, int index) +{ + auto playlist = Playlist::by_index (index); + + playlist.activate (); + + if (prefer_playing && aud_drct_get_playing ()) + playlist.start_playback (aud_drct_get_paused ()); + + FINISH (set_active_playlist); + return true; +} + +static gboolean do_set_active_playlist_name (Obj * obj, Invoc * invoc, const char * title) +{ + CURRENT.set_title (title); + FINISH (set_active_playlist_name); + return true; +} + +static gboolean do_set_eq (Obj * obj, Invoc * invoc, double preamp, GVariant * var) +{ + if (! g_variant_is_of_type (var, G_VARIANT_TYPE ("ad"))) + return false; + + size_t nbands = 0; + const double * bands = (double *) g_variant_get_fixed_array (var, & nbands, sizeof (double)); + + if (nbands != AUD_EQ_NBANDS) + return false; + + aud_set_double ("equalizer_preamp", preamp); + aud_eq_set_bands (bands); + FINISH (set_eq); + return true; +} + +static gboolean do_set_eq_band (Obj * obj, Invoc * invoc, int band, double value) +{ + aud_eq_set_band (band, value); + FINISH (set_eq_band); + return true; +} + +static gboolean do_set_eq_preamp (Obj * obj, Invoc * invoc, double preamp) +{ + aud_set_double ("equalizer_preamp", preamp); + FINISH (set_eq_preamp); + return true; +} + +static gboolean do_set_volume (Obj * obj, Invoc * invoc, int vl, int vr) +{ + aud_drct_set_volume ({vl, vr}); + FINISH (set_volume); + return true; +} + +static gboolean do_show_about_box (Obj * obj, Invoc * invoc, gboolean show) +{ + if (! aud_get_headless_mode ()) + { + if (show) + aud_ui_show_about_window (); + else + aud_ui_hide_about_window (); + } + + FINISH (show_about_box); + return true; +} + +static gboolean do_show_filebrowser (Obj * obj, Invoc * invoc, gboolean show) +{ + if (! aud_get_headless_mode ()) + { + if (show) + aud_ui_show_filebrowser (false); + else + aud_ui_hide_filebrowser (); + } + + FINISH (show_filebrowser); + return true; +} + +static gboolean do_show_jtf_box (Obj * obj, Invoc * invoc, gboolean show) +{ + if (! aud_get_headless_mode ()) + { + if (show) + aud_ui_show_jump_to_song (); + else + aud_ui_hide_jump_to_song (); + } + + FINISH (show_jtf_box); + return true; +} + +static gboolean do_show_main_win (Obj * obj, Invoc * invoc, gboolean show) +{ + if (! aud_get_headless_mode ()) + aud_ui_show (show); + + FINISH (show_main_win); + return true; +} + +static gboolean do_show_prefs_box (Obj * obj, Invoc * invoc, gboolean show) +{ + if (! aud_get_headless_mode ()) + { + if (show) + aud_ui_show_prefs_window (); + else + aud_ui_hide_prefs_window (); + } + + FINISH (show_prefs_box); + return true; +} + +static gboolean do_shuffle (Obj * obj, Invoc * invoc) +{ + FINISH2 (shuffle, aud_get_bool ("shuffle")); + return true; +} + +static gboolean do_song_filename (Obj * obj, Invoc * invoc, unsigned pos) +{ + String filename = CURRENT.entry_filename (pos); + FINISH2 (song_filename, filename ? filename : ""); + return true; +} + +static gboolean do_song_frames (Obj * obj, Invoc * invoc, unsigned pos) +{ + Tuple tuple = CURRENT.entry_tuple (pos); + FINISH2 (song_frames, aud::max (0, tuple.get_int (Tuple::Length))); + return true; +} + +static gboolean do_song_length (Obj * obj, Invoc * invoc, unsigned pos) +{ + Tuple tuple = CURRENT.entry_tuple (pos); + int length = aud::max (0, tuple.get_int (Tuple::Length)); + FINISH2 (song_length, length / 1000); + return true; +} + +static gboolean do_song_title (Obj * obj, Invoc * invoc, unsigned pos) +{ + Tuple tuple = CURRENT.entry_tuple (pos); + String title = tuple.get_str (Tuple::FormattedTitle); + FINISH2 (song_title, title ? title : ""); + return true; +} + +static gboolean do_song_tuple (Obj * obj, Invoc * invoc, unsigned pos, const char * key) +{ + Tuple::Field field = Tuple::field_by_name (key); + GVariant * var = nullptr; + + if (field >= 0) + { + Tuple tuple = CURRENT.entry_tuple (pos); + + switch (tuple.get_value_type (field)) + { + case Tuple::String: + var = g_variant_new_string (tuple.get_str (field)); + break; + + case Tuple::Int: + var = g_variant_new_int32 (tuple.get_int (field)); + break; + + default: + break; + } + } + + if (! var) + var = g_variant_new_string (""); + + FINISH2 (song_tuple, g_variant_new_variant (var)); + return true; +} + +static gboolean do_startup_notify (Obj * obj, Invoc * invoc, const char * id) +{ + aud_ui_startup_notify (id); + FINISH (startup_notify); + return true; +} + +static gboolean do_status (Obj * obj, Invoc * invoc) +{ + const char * status = "stopped"; + if (aud_drct_get_playing ()) + status = aud_drct_get_paused () ? "paused" : "playing"; + + FINISH2 (status, status); + return true; +} + +static gboolean do_stop (Obj * obj, Invoc * invoc) +{ + aud_drct_stop (); + FINISH (stop); + return true; +} + +static gboolean do_stop_after (Obj * obj, Invoc * invoc) +{ + FINISH2 (stop_after, aud_get_bool ("stop_after_current_song")); + return true; +} + +static gboolean do_stopped (Obj * obj, Invoc * invoc) +{ + FINISH2 (stopped, ! aud_drct_get_playing ()); + return true; +} + +static gboolean do_time (Obj * obj, Invoc * invoc) +{ + FINISH2 (time, aud_drct_get_time ()); + return true; +} + +static gboolean do_toggle_auto_advance (Obj * obj, Invoc * invoc) +{ + aud_toggle_bool ("no_playlist_advance"); + FINISH (toggle_auto_advance); + return true; +} + +static gboolean do_toggle_repeat (Obj * obj, Invoc * invoc) +{ + aud_toggle_bool ("repeat"); + FINISH (toggle_repeat); + return true; +} + +static gboolean do_toggle_shuffle (Obj * obj, Invoc * invoc) +{ + aud_toggle_bool ("shuffle"); + FINISH (toggle_shuffle); + return true; +} + +static gboolean do_toggle_stop_after (Obj * obj, Invoc * invoc) +{ + aud_toggle_bool ("stop_after_current_song"); + FINISH (toggle_stop_after); + return true; +} + +static gboolean do_version (Obj * obj, Invoc * invoc) +{ + FINISH2 (version, VERSION); + return true; +} + +static gboolean do_volume (Obj * obj, Invoc * invoc) +{ + StereoVolume volume = aud_drct_get_volume (); + FINISH2 (volume, volume.left, volume.right); + return true; +} + +static const struct +{ + const char * signal; + GCallback callback; +} +handlers[] = +{ + {"handle-add", (GCallback) do_add}, + {"handle-add-list", (GCallback) do_add_list}, + {"handle-add-url", (GCallback) do_add_url}, + {"handle-advance", (GCallback) do_advance}, + {"handle-advance-album", (GCallback) do_advance_album}, + {"handle-auto-advance", (GCallback) do_auto_advance}, + {"handle-balance", (GCallback) do_balance}, + {"handle-clear", (GCallback) do_clear}, + {"handle-config-get", (GCallback) do_config_get}, + {"handle-config-set", (GCallback) do_config_set}, + {"handle-delete", (GCallback) do_delete}, + {"handle-delete-active-playlist", (GCallback) do_delete_active_playlist}, + {"handle-eject", (GCallback) do_eject}, + {"handle-equalizer-activate", (GCallback) do_equalizer_activate}, + {"handle-get-active-playlist", (GCallback) do_get_active_playlist}, + {"handle-get-active-playlist-name", (GCallback) do_get_active_playlist_name}, + {"handle-get-eq", (GCallback) do_get_eq}, + {"handle-get-eq-band", (GCallback) do_get_eq_band}, + {"handle-get-eq-preamp", (GCallback) do_get_eq_preamp}, + {"handle-get-info", (GCallback) do_get_info}, + {"handle-get-playqueue-length", (GCallback) do_get_playqueue_length}, + {"handle-get-tuple-fields", (GCallback) do_get_tuple_fields}, + {"handle-info", (GCallback) do_info}, + {"handle-jump", (GCallback) do_jump}, + {"handle-length", (GCallback) do_length}, + {"handle-main-win-visible", (GCallback) do_main_win_visible}, + {"handle-new-playlist", (GCallback) do_new_playlist}, + {"handle-number-of-playlists", (GCallback) do_number_of_playlists}, + {"handle-open-list", (GCallback) do_open_list}, + {"handle-open-list-to-temp", (GCallback) do_open_list_to_temp}, + {"handle-pause", (GCallback) do_pause}, + {"handle-paused", (GCallback) do_paused}, + {"handle-play", (GCallback) do_play}, + {"handle-play-active-playlist", (GCallback) do_play_active_playlist}, + {"handle-play-pause", (GCallback) do_play_pause}, + {"handle-playing", (GCallback) do_playing}, + {"handle-playlist-add", (GCallback) do_playlist_add}, + {"handle-playlist-enqueue-to-temp", (GCallback) do_playlist_enqueue_to_temp}, + {"handle-playlist-ins-url-string", (GCallback) do_playlist_ins_url_string}, + {"handle-playqueue-add", (GCallback) do_playqueue_add}, + {"handle-playqueue-clear", (GCallback) do_playqueue_clear}, + {"handle-playqueue-is-queued", (GCallback) do_playqueue_is_queued}, + {"handle-playqueue-remove", (GCallback) do_playqueue_remove}, + {"handle-plugin-enable", (GCallback) do_plugin_enable}, + {"handle-plugin-is-enabled", (GCallback) do_plugin_is_enabled}, + {"handle-position", (GCallback) do_position}, + {"handle-queue-get-list-pos", (GCallback) do_queue_get_list_pos}, + {"handle-queue-get-queue-pos", (GCallback) do_queue_get_queue_pos}, + {"handle-quit", (GCallback) do_quit}, + {"handle-recording", (GCallback) do_recording}, + {"handle-record", (GCallback) do_record}, + {"handle-repeat", (GCallback) do_repeat}, + {"handle-reverse", (GCallback) do_reverse}, + {"handle-reverse-album", (GCallback) do_reverse_album}, + {"handle-seek", (GCallback) do_seek}, + {"handle-select-displayed-playlist", (GCallback) do_select_displayed_playlist}, + {"handle-select-playing-playlist", (GCallback) do_select_playing_playlist}, + {"handle-set-active-playlist", (GCallback) do_set_active_playlist}, + {"handle-set-active-playlist-name", (GCallback) do_set_active_playlist_name}, + {"handle-set-eq", (GCallback) do_set_eq}, + {"handle-set-eq-band", (GCallback) do_set_eq_band}, + {"handle-set-eq-preamp", (GCallback) do_set_eq_preamp}, + {"handle-set-volume", (GCallback) do_set_volume}, + {"handle-show-about-box", (GCallback) do_show_about_box}, + {"handle-show-filebrowser", (GCallback) do_show_filebrowser}, + {"handle-show-jtf-box", (GCallback) do_show_jtf_box}, + {"handle-show-main-win", (GCallback) do_show_main_win}, + {"handle-show-prefs-box", (GCallback) do_show_prefs_box}, + {"handle-shuffle", (GCallback) do_shuffle}, + {"handle-song-filename", (GCallback) do_song_filename}, + {"handle-song-frames", (GCallback) do_song_frames}, + {"handle-song-length", (GCallback) do_song_length}, + {"handle-song-title", (GCallback) do_song_title}, + {"handle-song-tuple", (GCallback) do_song_tuple}, + {"handle-startup-notify", (GCallback) do_startup_notify}, + {"handle-status", (GCallback) do_status}, + {"handle-stop", (GCallback) do_stop}, + {"handle-stop-after", (GCallback) do_stop_after}, + {"handle-stopped", (GCallback) do_stopped}, + {"handle-time", (GCallback) do_time}, + {"handle-toggle-auto-advance", (GCallback) do_toggle_auto_advance}, + {"handle-toggle-repeat", (GCallback) do_toggle_repeat}, + {"handle-toggle-shuffle", (GCallback) do_toggle_shuffle}, + {"handle-toggle-stop-after", (GCallback) do_toggle_stop_after}, + {"handle-version", (GCallback) do_version}, + {"handle-volume", (GCallback) do_volume} +}; + +static GMainLoop * mainloop = nullptr; +static unsigned owner_id = 0; + +static GDBusInterfaceSkeleton * skeleton = nullptr; + +static void name_acquired (GDBusConnection *, const char * name, void *) +{ + AUDINFO ("Owned D-Bus name (%s) on session bus.\n", name); + + g_main_loop_quit (mainloop); +} + +static void name_lost (GDBusConnection *, const char * name, void *) +{ + AUDINFO ("Owning D-Bus name (%s) failed, already taken?\n", name); + + g_bus_unown_name (owner_id); + owner_id = 0; + + g_main_loop_quit (mainloop); +} + +StringBuf dbus_server_name () +{ + int instance = aud_get_instance (); + return (instance == 1) ? str_copy ("org.atheme.audacious") : + str_printf ("org.atheme.audacious-%d", instance); +} + +StartupType dbus_server_init () +{ + auto startup = StartupType::Unknown; + + GError * error = nullptr; + GDBusConnection * bus = g_bus_get_sync (G_BUS_TYPE_SESSION, nullptr, & error); + GMainContext * context; + + if (! bus) + goto ERROR; + + skeleton = (GDBusInterfaceSkeleton *) obj_audacious_skeleton_new (); + + for (auto & handler : handlers) + g_signal_connect (skeleton, handler.signal, handler.callback, nullptr); + + if (! g_dbus_interface_skeleton_export (skeleton, bus, "/org/atheme/audacious", & error)) + goto ERROR; + + context = g_main_context_new (); + g_main_context_push_thread_default (context); + + owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, dbus_server_name (), + (GBusNameOwnerFlags) 0, nullptr, name_acquired, name_lost, nullptr, nullptr); + + mainloop = g_main_loop_new (context, true); + g_main_loop_run (mainloop); + g_main_loop_unref (mainloop); + mainloop = nullptr; + + if (owner_id) + startup = StartupType::Server; + else + startup = StartupType::Client; + + g_main_context_pop_thread_default (context); + g_main_context_unref (context); + +ERROR: + if (error) + { + AUDERR ("D-Bus error: %s\n", error->message); + g_error_free (error); + } + + if (startup != StartupType::Server) + dbus_server_cleanup (); + + return startup; +} + +void dbus_server_cleanup () +{ + if (owner_id) + { + g_bus_unown_name (owner_id); + owner_id = 0; + } + + if (skeleton) + { + g_object_unref (skeleton); + skeleton = nullptr; + } +} diff --git a/src/audacious/main.cc b/src/audacious/main.cc new file mode 100644 index 0000000..1213a95 --- /dev/null +++ b/src/audacious/main.cc @@ -0,0 +1,408 @@ +/* + * main.c + * Copyright 2007-2013 Ariadne Conill and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include +#include +#include + +#ifdef _WIN32 +#include +#endif + +#define AUD_GLIB_INTEGRATION +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_DBUS +#include "aud-dbus.h" +#endif + +#include "main.h" +#include "util.h" + +static struct { + int help, version; + int play, pause, play_pause, stop, fwd, rew; + int enqueue, enqueue_to_temp; + int mainwin, show_jump_box; + int headless, quit_after_play; + int verbose; + int gtk; +} options; + +static bool initted = false; +static Index filenames; + +static const struct { + const char * long_arg; + char short_arg; + int * value; + const char * desc; +} arg_map[] = { + {"help", 'h', & options.help, N_("Show command-line help")}, + {"version", 'v', & options.version, N_("Show version")}, + {"play", 'p', & options.play, N_("Start playback")}, + {"pause", 'u', & options.pause, N_("Pause playback")}, + {"play-pause", 't', & options.play_pause, N_("Pause if playing, play otherwise")}, + {"stop", 's', & options.stop, N_("Stop playback")}, + {"rew", 'r', & options.rew, N_("Skip to previous song")}, + {"fwd", 'f', & options.fwd, N_("Skip to next song")}, + {"enqueue", 'e', & options.enqueue, N_("Add files to the playlist")}, + {"enqueue-to-temp", 'E', & options.enqueue_to_temp, N_("Add files to a temporary playlist")}, + {"show-main-window", 'm', & options.mainwin, N_("Display the main window")}, + {"show-jump-box", 'j', & options.show_jump_box, N_("Display the jump-to-song window")}, + {"headless", 'H', & options.headless, N_("Start without a graphical interface")}, + {"quit-after-play", 'q', & options.quit_after_play, N_("Quit on playback stop")}, + {"verbose", 'V', & options.verbose, N_("Print debugging messages (may be used twice)")}, +#if defined(USE_QT) && defined(USE_GTK) + {"gtk", 'G', & options.gtk, N_("Run in GTK mode")}, +#endif +}; + +static bool parse_options (int argc, char * * argv) +{ + CharPtr cur (g_get_current_dir ()); + +#ifdef _WIN32 + Index args = get_argv_utf8 (); + + for (int n = 1; n < args.len (); n ++) + { + const char * arg = args[n]; +#else + for (int n = 1; n < argc; n ++) + { + const char * arg = argv[n]; +#endif + + if (arg[0] != '-') /* filename */ + { + String uri; + + if (strstr (arg, "://")) + uri = String (arg); + else if (g_path_is_absolute (arg)) + uri = String (filename_to_uri (arg)); + else + uri = String (filename_to_uri (filename_build ({cur, arg}))); + + filenames.append (uri); + } + else if (! arg[1]) /* "-" (standard input) */ + { + filenames.append (String ("stdin://")); + } + else if (arg[1] >= '1' && arg[1] <= '9') /* instance number */ + { + aud_set_instance (arg[1] - '0'); + } + else if (arg[1] == '-') /* long option */ + { + bool found = false; + + for (auto & arg_info : arg_map) + { + if (! strcmp (arg + 2, arg_info.long_arg)) + { + (* arg_info.value) ++; + found = true; + break; + } + } + + if (! found) + { + fprintf (stderr, _("Unknown option: %s\n"), arg); + return false; + } + } + else /* short form */ + { + for (int c = 1; arg[c]; c ++) + { + bool found = false; + + for (auto & arg_info : arg_map) + { + if (arg[c] == arg_info.short_arg) + { + (* arg_info.value) ++; + found = true; + break; + } + } + + if (! found) + { + fprintf (stderr, _("Unknown option: -%c\n"), arg[c]); + return false; + } + } + } + } + + aud_set_headless_mode (options.headless); + + if (options.verbose >= 2) + audlog::set_stderr_level (audlog::Debug); + else if (options.verbose) + audlog::set_stderr_level (audlog::Info); + + if (options.gtk) + aud_set_mainloop_type (MainloopType::GLib); + + return true; +} + +static void print_help () +{ + static const char pad[21] = " "; + + fprintf (stderr, "%s", _("Usage: audacious [OPTION] ... [FILE] ...\n\n")); + fprintf (stderr, " -1, -2, -3, etc. %s\n", _("Select instance to run/control")); + + for (auto & arg_info : arg_map) + fprintf (stderr, " -%c, --%s%.*s%s\n", arg_info.short_arg, + arg_info.long_arg, (int) (20 - strlen (arg_info.long_arg)), pad, + _(arg_info.desc)); + + fprintf (stderr, "\n"); +} + +#ifdef USE_DBUS +static void do_remote () +{ + GDBusConnection * bus = nullptr; + ObjAudacious * obj = nullptr; + GError * error = nullptr; + + g_type_init (); + + /* check whether the selected instance is running */ + if (dbus_server_init () != StartupType::Client) + return; + + if (! (bus = g_bus_get_sync (G_BUS_TYPE_SESSION, nullptr, & error)) || + ! (obj = obj_audacious_proxy_new_sync (bus, (GDBusProxyFlags) 0, + dbus_server_name (), "/org/atheme/audacious", nullptr, & error))) + { + AUDERR ("D-Bus error: %s\n", error->message); + g_error_free (error); + return; + } + + AUDINFO ("Connected to remote session.\n"); + + /* if no command line options, then present running instance */ + if (! (filenames.len () || options.play || options.pause || + options.play_pause || options.stop || options.rew || options.fwd || + options.show_jump_box || options.mainwin)) + options.mainwin = true; + + if (filenames.len ()) + { + Index list; + + for (auto & item : filenames) + list.append (item.filename); + + list.append (nullptr); + + if (options.enqueue_to_temp) + obj_audacious_call_open_list_to_temp_sync (obj, list.begin (), nullptr, nullptr); + else if (options.enqueue) + obj_audacious_call_add_list_sync (obj, list.begin (), nullptr, nullptr); + else + obj_audacious_call_open_list_sync (obj, list.begin (), nullptr, nullptr); + } + + if (options.play) + obj_audacious_call_play_sync (obj, nullptr, nullptr); + if (options.pause) + obj_audacious_call_pause_sync (obj, nullptr, nullptr); + if (options.play_pause) + obj_audacious_call_play_pause_sync (obj, nullptr, nullptr); + if (options.stop) + obj_audacious_call_stop_sync (obj, nullptr, nullptr); + if (options.rew) + obj_audacious_call_reverse_sync (obj, nullptr, nullptr); + if (options.fwd) + obj_audacious_call_advance_sync (obj, nullptr, nullptr); + if (options.show_jump_box) + obj_audacious_call_show_jtf_box_sync (obj, true, nullptr, nullptr); + if (options.mainwin) + obj_audacious_call_show_main_win_sync (obj, true, nullptr, nullptr); + + const char * startup_id = getenv ("DESKTOP_STARTUP_ID"); + if (startup_id) + obj_audacious_call_startup_notify_sync (obj, startup_id, nullptr, nullptr); + + g_object_unref (obj); + + exit (EXIT_SUCCESS); +} +#endif + +static void do_commands () +{ + bool resume = aud_get_bool ("resume_playback_on_startup"); + + if (filenames.len ()) + { + if (options.enqueue_to_temp) + { + aud_drct_pl_open_temp_list (std::move (filenames)); + resume = false; + } + else if (options.enqueue) + aud_drct_pl_add_list (std::move (filenames), -1); + else + { + aud_drct_pl_open_list (std::move (filenames)); + resume = false; + } + } + + if (resume) + aud_resume (); + + if (options.play || options.play_pause) + { + if (! aud_drct_get_playing ()) + aud_drct_play (); + else if (aud_drct_get_paused ()) + aud_drct_pause (); + } +} + +static void do_commands_at_idle (void *) +{ + if (options.show_jump_box && ! options.headless) + aud_ui_show_jump_to_song (); + if (options.mainwin && ! options.headless) + aud_ui_show (true); +} + +static void main_cleanup () +{ + if (initted) + { + /* Somebody was naughty and called exit() instead of aud_quit(). + * aud_cleanup() has not been called yet, so there's no point in running + * leak checks. Note that it's not safe to call aud_cleanup() from the + * exit handler, since we don't know what context we're in (we could be + * deep inside the call tree of some plugin, for example). */ + AUDWARN ("exit() called unexpectedly; skipping normal cleanup.\n"); + return; + } + + filenames.clear (); + aud_leak_check (); +} + +static bool check_should_quit () +{ + return options.quit_after_play && ! aud_drct_get_playing () && + ! Playlist::add_in_progress_any (); +} + +static void maybe_quit () +{ + if (check_should_quit ()) + aud_quit (); +} + +int main (int argc, char * * argv) +{ + atexit (main_cleanup); + +#ifdef _WIN32 + SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); +#endif +#ifdef HAVE_SIGWAIT + signals_init_one (); +#endif + + aud_init_i18n (); + + if (! parse_options (argc, argv)) + { + print_help (); + return EXIT_FAILURE; + } + + if (options.help) + { + print_help (); + return EXIT_SUCCESS; + } + + if (options.version) + { + printf ("%s %s (%s)\n", _("Audacious"), VERSION, BUILDSTAMP); + return EXIT_SUCCESS; + } + +#ifdef USE_DBUS + do_remote (); /* may exit */ +#endif + + AUDINFO ("No remote session; starting up.\n"); + +#ifdef HAVE_SIGWAIT + signals_init_two (); +#endif + + initted = true; + aud_init (); + + do_commands (); + + if (! check_should_quit ()) + { + QueuedFunc at_idle_func; + at_idle_func.queue (do_commands_at_idle, nullptr); + + hook_associate ("playback stop", (HookFunction) maybe_quit, nullptr); + hook_associate ("playlist add complete", (HookFunction) maybe_quit, nullptr); + hook_associate ("quit", (HookFunction) aud_quit, nullptr); + + aud_run (); + + hook_dissociate ("playback stop", (HookFunction) maybe_quit); + hook_dissociate ("playlist add complete", (HookFunction) maybe_quit); + hook_dissociate ("quit", (HookFunction) aud_quit); + } + +#ifdef USE_DBUS + dbus_server_cleanup (); +#endif + + aud_cleanup (); + initted = false; + + return EXIT_SUCCESS; +} diff --git a/src/audacious/main.h b/src/audacious/main.h new file mode 100644 index 0000000..26d3b89 --- /dev/null +++ b/src/audacious/main.h @@ -0,0 +1,46 @@ +/* + * main.h + * Copyright 2011-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef _AUDACIOUS_MAIN_H +#define _AUDACIOUS_MAIN_H + +#include + +/* dbus-server.c */ +#ifdef USE_DBUS + +enum class StartupType { + Server, + Client, + Unknown +}; + +StringBuf dbus_server_name (); +StartupType dbus_server_init (); +void dbus_server_cleanup (); + +#endif + +/* signals.c */ +#ifdef HAVE_SIGWAIT +void signals_init_one (); +void signals_init_two (); +#endif + +#endif diff --git a/src/audacious/meson.build b/src/audacious/meson.build new file mode 100644 index 0000000..d91ba79 --- /dev/null +++ b/src/audacious/meson.build @@ -0,0 +1,24 @@ +audacious_deps = [glib_dep] +audacious_libs = [libaudcore_lib] + +audacious_sources = [ + 'main.cc', + 'signals.cc', + 'util.cc' +] + + +if get_option('dbus') + audacious_sources += ['dbus-server.cc'] + audacious_libs += [aud_dbus_lib] + audacious_deps += [aud_dbus_deps] +endif + + +audacious_exe = executable('audacious', + audacious_sources, + include_directories: [src_inc, aud_dbus_inc], + dependencies: audacious_deps, + link_with: audacious_libs, + install: true +) diff --git a/src/audacious/signals.cc b/src/audacious/signals.cc new file mode 100644 index 0000000..8ed1fec --- /dev/null +++ b/src/audacious/signals.cc @@ -0,0 +1,56 @@ +/* + * signals.c + * Copyright 2009 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifdef HAVE_SIGWAIT + +#include + +#include +#include + +#include "main.h" + +static sigset_t signal_set; + +static void signal_thread () +{ + int signal; + + while (! sigwait (& signal_set, & signal)) + event_queue ("quit", nullptr); +} + +/* Must be called before any threads are created. */ +void signals_init_one () +{ + sigemptyset (& signal_set); + sigaddset (& signal_set, SIGHUP); + sigaddset (& signal_set, SIGINT); + sigaddset (& signal_set, SIGQUIT); + sigaddset (& signal_set, SIGTERM); + + sigprocmask (SIG_BLOCK, & signal_set, nullptr); +} + +void signals_init_two () +{ + std::thread (signal_thread).detach (); +} + +#endif /* HAVE_SIGWAIT */ diff --git a/src/audacious/util.cc b/src/audacious/util.cc new file mode 100644 index 0000000..c4449de --- /dev/null +++ b/src/audacious/util.cc @@ -0,0 +1,48 @@ +/* + * util.c + * Copyright 2009-2013 John Lindgren and Michał Lipski + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "util.h" + +#ifdef _WIN32 +#include + +#ifdef WORDS_BIGENDIAN +#define UTF16_NATIVE "UTF-16BE" +#else +#define UTF16_NATIVE "UTF-16LE" +#endif + +Index get_argv_utf8 () +{ + int argc; + wchar_t * combined = GetCommandLineW (); + wchar_t * * split = CommandLineToArgvW (combined, & argc); + + Index argv; + argv.insert (0, argc); + + for (int i = 0; i < argc; i ++) + argv[i] = String (str_convert ((char *) split[i], + wcslen (split[i]) * sizeof (wchar_t), UTF16_NATIVE, "UTF-8")); + + LocalFree (split); + return argv; +} + +#endif diff --git a/src/audacious/util.h b/src/audacious/util.h new file mode 100644 index 0000000..55bfd6b --- /dev/null +++ b/src/audacious/util.h @@ -0,0 +1,29 @@ +/* + * util.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef AUDACIOUS_UTIL_H +#define AUDACIOUS_UTIL_H + +#include + +#ifdef _WIN32 +Index get_argv_utf8 (); +#endif + +#endif /* AUDACIOUS_UTIL_H */ diff --git a/src/audtool/Makefile b/src/audtool/Makefile new file mode 100644 index 0000000..90c822c --- /dev/null +++ b/src/audtool/Makefile @@ -0,0 +1,18 @@ +PROG = audtool +SRCS = main.c \ + handlers_general.c \ + handlers_playback.c \ + handlers_playlist.c \ + handlers_playqueue.c \ + handlers_vitals.c \ + handlers_equalizer.c \ + report.c \ + wrappers.c + +EXT_DEPS += ../dbus/aud-dbus.a + +include ../../buildsys.mk +include ../../extra.mk + +CPPFLAGS := -I../.. -I../dbus ${CPPFLAGS} ${GLIB_CFLAGS} ${GIO_CFLAGS} +LIBS := ../dbus/aud-dbus.a ${LIBS} ${GLIB_LIBS} ${GIO_LIBS} diff --git a/src/audtool/audtool.h b/src/audtool/audtool.h new file mode 100644 index 0000000..7a1e3a9 --- /dev/null +++ b/src/audtool/audtool.h @@ -0,0 +1,147 @@ +/* + * audtool.h + * Copyright 2005-2011 Ariadne Conill, George Averill, Giacomo Lozito, + * Yoshiki Yazawa, Matti Hämäläinen, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef AUDTOOL_H +#define AUDTOOL_H + +#include "aud-dbus.h" + +struct commandhandler +{ + const char * name; + void (* handler) (int argc, char * * argv); + const char * desc; + int args; +}; + +extern const struct commandhandler handlers[]; +extern ObjAudacious * dbus_proxy; + +void audtool_report (const char * str, ...); +void audtool_whine (const char * str, ...); +void audtool_whine_args (const char * name, const char * str, ...); +void audtool_whine_tuple_fields (void); + +void get_handlers_list (int, char * *); +void get_current_song (int, char * *); +void get_current_song_filename (int, char * *); +void get_current_song_length (int, char * *); +void get_current_song_length_seconds (int, char * *); +void get_current_song_length_frames (int, char * *); +void get_current_song_output_length (int, char * *); +void get_current_song_output_length_seconds (int, char * *); +void get_current_song_output_length_frames (int, char * *); +void get_current_song_bitrate (int, char * *); +void get_current_song_bitrate_kbps (int, char * *); +void get_current_song_frequency (int, char * *); +void get_current_song_frequency_khz (int, char * *); +void get_current_song_channels (int, char * *); +void get_current_song_tuple_field_data (int, char * * argv); +void get_current_song_info (int argc, char * * argv); + +void get_volume (int, char * *); +void set_volume (int, char * *); + +void select_displayed (int, char * *); +void select_playing (int, char * *); +void playlist_position (int, char * *); +void playlist_advance (int, char * *); +void playlist_advance_album (int, char * *); +void playlist_auto_advance_status (int, char * *); +void playlist_auto_advance_toggle (int, char * *); +void playlist_reverse (int, char * *); +void playlist_reverse_album (int, char * *); +void playlist_length (int, char * *); +void playlist_song (int, char * *); +void playlist_song_filename (int, char * *); +void playlist_song_length (int, char * *); +void playlist_song_length_seconds (int, char * *); +void playlist_song_length_frames (int, char * *); +void playlist_display (int, char * *); +void playlist_position (int, char * *); +void playlist_jump (int, char * *); +void playlist_add_url_string (int, char * *); +void playlist_delete (int, char * *); +void playlist_clear (int, char * *); +void playlist_repeat_status (int, char * *); +void playlist_repeat_toggle (int, char * *); +void playlist_shuffle_status (int, char * *); +void playlist_shuffle_toggle (int, char * *); +void playlist_stop_after_status (int argc, char * * argv); +void playlist_stop_after_toggle (int argc, char * * argv); +void playlist_tuple_field_data (int, char * * argv); +void playlist_enqueue_to_temp (int argc, char * * argv); +void playlist_ins_url_string (int argc, char * * argv); + +void number_of_playlists (int argc, char * * argv); +void current_playlist (int argc, char * * argv); +void set_current_playlist (int argc, char * * argv); +void playlist_title (int argc, char * * argv); +void set_playlist_title (int argc, char * * argv); +void new_playlist (int argc, char * * argv); +void delete_current_playlist (int argc, char * * argv); +void play_current_playlist (int argc, char * * argv); + +void playqueue_add (int, char * *); +void playqueue_remove (int, char * *); +void playqueue_is_queued (int, char * *); +void playqueue_get_queue_position (int, char * *); +void playqueue_get_list_position (int, char * *); +void playqueue_display (int, char * *); +void playqueue_length (int, char * *); +void playqueue_clear (int, char * *); + +void playback_play (int, char * *); +void playback_pause (int, char * *); +void playback_playpause (int, char * *); +void playback_stop (int, char * *); +void playback_playing (int, char * *); +void playback_paused (int, char * *); +void playback_stopped (int, char * *); +void playback_status (int, char * *); +void playback_seek (int, char * *); +void playback_seek_relative (int, char * *); +void playback_record (int, char * *); +void playback_recording (int, char * *); + +void mainwin_show (int, char * *); +void show_preferences_window (int, char * *); +void show_jtf_window (int, char * *); +void show_filebrowser (int, char * *); +void shutdown_audacious_server (int, char * *); +void show_about_window (int, char * *); + +void get_version (int argc, char * * argv); +void plugin_is_enabled (int argc, char * * argv); +void plugin_enable (int argc, char * * argv); +void config_get (int argc, char * * argv); +void config_set (int argc, char * * argv); + +void equalizer_get_eq (int argc, char * * argv); +void equalizer_get_eq_preamp (int argc, char * * argv); +void equalizer_get_eq_band (int argc, char * * argv); +void equalizer_set_eq (int argc, char * * argv); +void equalizer_set_eq_preamp (int argc, char * * argv); +void equalizer_set_eq_band (int argc, char * * argv); +void equalizer_active (int argc, char * * argv); + +int check_args_playlist_pos (int argc, char * * argv); + +#endif diff --git a/src/audtool/handlers_equalizer.c b/src/audtool/handlers_equalizer.c new file mode 100644 index 0000000..4c70126 --- /dev/null +++ b/src/audtool/handlers_equalizer.c @@ -0,0 +1,123 @@ +/* + * handlers_equalizer.c + * Copyright 2007-2013 Yoshiki Yazawa, Matti Hämäläinen, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include +#include + +#include "audtool.h" +#include "wrappers.h" + +#define NUM_BANDS 10 + +void equalizer_get_eq (int argc, char * * argv) +{ + double preamp = 0.0; + GVariant * var = NULL; + + obj_audacious_call_get_eq_sync (dbus_proxy, & preamp, & var, NULL, NULL); + + if (! var || ! g_variant_is_of_type (var, G_VARIANT_TYPE ("ad"))) + exit (1); + + audtool_report ("preamp = %.2f", preamp); + + size_t nbands = 0; + const double * bands = g_variant_get_fixed_array (var, & nbands, sizeof (double)); + + if (nbands != NUM_BANDS) + exit (1); + + for (int i = 0; i < NUM_BANDS; i ++) + printf ("%.2f ", bands[i]); + + printf ("\n"); + g_variant_unref (var); +} + +void equalizer_get_eq_preamp (int argc, char * * argv) +{ + double preamp = 0; + obj_audacious_call_get_eq_preamp_sync (dbus_proxy, & preamp, NULL, NULL); + audtool_report ("preamp = %.2f", preamp); +} + +void equalizer_get_eq_band (int argc, char * * argv) +{ + if (argc < 2) + { + audtool_whine_args (argv[0], ""); + exit (1); + } + + int band = atoi (argv[1]); + + double level = 0; + obj_audacious_call_get_eq_band_sync (dbus_proxy, band, & level, NULL, NULL); + audtool_report ("band %d = %.2f", band, level); +} + +void equalizer_set_eq (int argc, char * * argv) +{ + if (argc < 2 + NUM_BANDS) + { + audtool_whine_args (argv[0], " " + " "); + exit (1); + } + + double preamp = atof (argv[1]); + double bands[NUM_BANDS]; + + for (int i = 0; i < NUM_BANDS; i ++) + bands[i] = atof (argv[i + 2]); + + GVariant * var = g_variant_new_fixed_array (G_VARIANT_TYPE_DOUBLE, bands, + NUM_BANDS, sizeof (double)); + obj_audacious_call_set_eq_sync (dbus_proxy, preamp, var, NULL, NULL); +} + +void equalizer_set_eq_preamp (int argc, char * * argv) +{ + if (argc < 2) + { + audtool_whine_args (argv[0], ""); + exit (1); + } + + double preamp = atof (argv[1]); + obj_audacious_call_set_eq_preamp_sync (dbus_proxy, preamp, NULL, NULL); +} + +void equalizer_set_eq_band (int argc, char * * argv) +{ + if (argc < 3) + { + audtool_whine_args (argv[0], " "); + exit (1); + } + + int band = atoi (argv[1]); + double level = atof (argv[2]); + obj_audacious_call_set_eq_band_sync (dbus_proxy, band, level, NULL, NULL); +} + +void equalizer_active (int argc, char * * argv) +{ + generic_on_off (argc, argv, obj_audacious_call_equalizer_activate_sync); +} diff --git a/src/audtool/handlers_general.c b/src/audtool/handlers_general.c new file mode 100644 index 0000000..d03c63b --- /dev/null +++ b/src/audtool/handlers_general.c @@ -0,0 +1,200 @@ +/* + * handlers_general.c + * Copyright 2005-2013 George Averill, Ariadne Conill, Giacomo Lozito, + * Matti Hämäläinen, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include +#include + +#include "audtool.h" +#include "wrappers.h" + +static int get_main_volume (void) +{ + int left = 0, right = 0; + obj_audacious_call_volume_sync (dbus_proxy, & left, & right, NULL, NULL); + return MAX (left, right); +} + +void get_volume (int argc, char * * argv) +{ + audtool_report ("%d", get_main_volume ()); +} + +void set_volume (int argc, char * * argv) +{ + if (argc < 2) + { + audtool_whine_args (argv[0], ""); + exit (1); + } + + int vol = atoi (argv[1]); + + switch (argv[1][0]) + { + case '+': + case '-': + vol += get_main_volume (); + break; + } + + obj_audacious_call_set_volume_sync (dbus_proxy, vol, vol, NULL, NULL); +} + +void mainwin_show (int argc, char * * argv) +{ + generic_on_off (argc, argv, obj_audacious_call_show_main_win_sync); +} + +void show_preferences_window (int argc, char * * argv) +{ + generic_on_off (argc, argv, obj_audacious_call_show_prefs_box_sync); +} + +void show_about_window (int argc, char * * argv) +{ + generic_on_off (argc, argv, obj_audacious_call_show_about_box_sync); +} + +void show_jtf_window (int argc, char * * argv) +{ + generic_on_off (argc, argv, obj_audacious_call_show_jtf_box_sync); +} + +void show_filebrowser (int argc, char * * argv) +{ + generic_on_off (argc, argv, obj_audacious_call_show_filebrowser_sync); +} + +void shutdown_audacious_server (int argc, char * * argv) +{ + obj_audacious_call_quit_sync (dbus_proxy, NULL, NULL); +} + +void get_handlers_list (int argc, char * * argv) +{ + audtool_report ("Usage: audtool [-#] COMMAND ..."); + audtool_report (" where # (1-9) selects the instance of Audacious to control"); + audtool_report (""); + + for (int i = 0; handlers[i].name; i ++) + { + if (! g_ascii_strcasecmp ("", handlers[i].name)) + audtool_report ("%s%s:", i == 0 ? "" : "\n", handlers[i].desc); + else + audtool_report (" %-34s - %s", handlers[i].name, handlers[i].desc); + } + + audtool_report (""); + audtool_report ("Commands may be prefixed with '--' (GNU-style long options) or not, your choice."); + audtool_report ("Show/hide and enable/disable commands take an optional 'on' or 'off' argument."); + audtool_report ("Report bugs to https://redmine.audacious-media-player.org/projects/audacious"); +} + +void get_version (int argc, char * * argv) +{ + char * version = NULL; + obj_audacious_call_version_sync (dbus_proxy, & version, NULL, NULL); + + if (! version) + exit (1); + + audtool_report ("Audacious %s", version); + g_free (version); +} + +void plugin_is_enabled (int argc, char * * argv) +{ + if (argc != 2) + { + audtool_whine_args (argv[0], ""); + exit (1); + } + + gboolean enabled = FALSE; + obj_audacious_call_plugin_is_enabled_sync (dbus_proxy, argv[1], & enabled, NULL, NULL); + + exit (! enabled); +} + +void plugin_enable (int argc, char * * argv) +{ + gboolean enable = TRUE; + + if (argc == 2) + enable = TRUE; + else if (argc == 3 && ! g_ascii_strcasecmp (argv[2], "on")) + enable = TRUE; + else if (argc == 3 && ! g_ascii_strcasecmp (argv[2], "off")) + enable = FALSE; + else + { + audtool_whine_args (argv[0], " "); + exit (1); + } + + obj_audacious_call_plugin_enable_sync (dbus_proxy, argv[1], enable, NULL, NULL); +} + +void config_get (int argc, char * * argv) +{ + if (argc != 2) + { + audtool_whine_args (argv[0], "[
:]"); + exit (1); + } + + const char * section = ""; + const char * name = argv[1]; + char * colon = strchr (argv[1], ':'); + + if (colon) + { + * colon = 0; + section = argv[1]; + name = colon + 1; + } + + char * value = NULL; + obj_audacious_call_config_get_sync (dbus_proxy, section, name, & value, NULL, NULL); + audtool_report (value); + g_free (value); +} + +void config_set (int argc, char * * argv) +{ + if (argc != 3) + { + audtool_whine_args (argv[0], "[
:] "); + exit (1); + } + + const char * section = ""; + const char * name = argv[1]; + char * colon = strchr (argv[1], ':'); + + if (colon) + { + * colon = 0; + section = argv[1]; + name = colon + 1; + } + + obj_audacious_call_config_set_sync (dbus_proxy, section, name, argv[2], NULL, NULL); +} diff --git a/src/audtool/handlers_playback.c b/src/audtool/handlers_playback.c new file mode 100644 index 0000000..c9ba722 --- /dev/null +++ b/src/audtool/handlers_playback.c @@ -0,0 +1,116 @@ +/* + * handlers_playback.c + * Copyright 2005-2013 George Averill, Ariadne Conill, Matti Hämäläinen, and + * John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include + +#include "audtool.h" + +void playback_play (int argc, char * * argv) +{ + obj_audacious_call_play_sync (dbus_proxy, NULL, NULL); +} + +void playback_pause (int argc, char * * argv) +{ + obj_audacious_call_pause_sync (dbus_proxy, NULL, NULL); +} + +void playback_playpause (int argc, char * * argv) +{ + obj_audacious_call_play_pause_sync (dbus_proxy, NULL, NULL); +} + +void playback_stop (int argc, char * * argv) +{ + obj_audacious_call_stop_sync (dbus_proxy, NULL, NULL); +} + +void playback_playing (int argc, char * * argv) +{ + gboolean playing = FALSE; + obj_audacious_call_playing_sync (dbus_proxy, & playing, NULL, NULL); + + exit (! playing); +} + +void playback_paused (int argc, char * * argv) +{ + gboolean paused = FALSE; + obj_audacious_call_paused_sync (dbus_proxy, & paused, NULL, NULL); + + exit (! paused); +} + +void playback_stopped (int argc, char * * argv) +{ + gboolean stopped = FALSE; + obj_audacious_call_stopped_sync (dbus_proxy, & stopped, NULL, NULL); + + exit (! stopped); +} + +void playback_status (int argc, char * * argv) +{ + char * status = NULL; + obj_audacious_call_status_sync (dbus_proxy, & status, NULL, NULL); + + if (! status) + exit (1); + + audtool_report ("%s", status); + g_free (status); +} + +void playback_seek (int argc, char * * argv) +{ + if (argc < 2) + { + audtool_whine_args (argv[0], ""); + exit (1); + } + + obj_audacious_call_seek_sync (dbus_proxy, MAX (0, atof (argv[1]) * 1000), NULL, NULL); +} + +void playback_seek_relative (int argc, char * * argv) +{ + if (argc < 2) + { + audtool_whine_args (argv[0], ""); + exit (1); + } + + unsigned oldtime = 0; + obj_audacious_call_time_sync (dbus_proxy, & oldtime, NULL, NULL); + obj_audacious_call_seek_sync (dbus_proxy, MAX (0, oldtime + atof (argv[1]) * 1000), NULL, NULL); +} + +void playback_record (int argc, char * * argv) +{ + obj_audacious_call_record_sync (dbus_proxy, NULL, NULL); +} + +void playback_recording (int argc, char * * argv) +{ + gboolean recording = FALSE; + obj_audacious_call_recording_sync (dbus_proxy, & recording, NULL, NULL); + + exit (! recording); +} diff --git a/src/audtool/handlers_playlist.c b/src/audtool/handlers_playlist.c new file mode 100644 index 0000000..e97d794 --- /dev/null +++ b/src/audtool/handlers_playlist.c @@ -0,0 +1,386 @@ +/* + * handlers_playlist.c + * Copyright 2005-2013 George Averill, Ariadne Conill, Yoshiki Yazawa, + * Matti Hämäläinen, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include +#include + +#include "audtool.h" +#include "wrappers.h" + +void select_displayed (int argc, char * * argv) +{ + obj_audacious_call_select_displayed_playlist_sync (dbus_proxy, NULL, NULL); +} + +void select_playing (int argc, char * * argv) +{ + obj_audacious_call_select_playing_playlist_sync (dbus_proxy, NULL, NULL); +} + +void playlist_reverse (int argc, char * * argv) +{ + obj_audacious_call_reverse_sync (dbus_proxy, NULL, NULL); +} + +void playlist_reverse_album (int argc, char * * argv) +{ + obj_audacious_call_reverse_album_sync (dbus_proxy, NULL, NULL); +} + +void playlist_advance (int argc, char * * argv) +{ + obj_audacious_call_advance_sync (dbus_proxy, NULL, NULL); +} + +void playlist_advance_album (int argc, char * * argv) +{ + obj_audacious_call_advance_album_sync (dbus_proxy, NULL, NULL); +} + +void playlist_auto_advance_status (int argc, char * * argv) +{ + gboolean advance = FALSE; + obj_audacious_call_auto_advance_sync (dbus_proxy, & advance, NULL, NULL); + audtool_report (advance ? "on" : "off"); +} + +void playlist_auto_advance_toggle (int argc, char * * argv) +{ + obj_audacious_call_toggle_auto_advance_sync (dbus_proxy, NULL, NULL); +} + +void playlist_stop_after_status (int argc, char * * argv) +{ + gboolean stop_after = FALSE; + obj_audacious_call_stop_after_sync (dbus_proxy, & stop_after, NULL, NULL); + audtool_report (stop_after ? "on" : "off"); +} + +void playlist_stop_after_toggle (int argc, char * * argv) +{ + obj_audacious_call_toggle_stop_after_sync (dbus_proxy, NULL, NULL); +} + +int check_args_playlist_pos (int argc, char * * argv) +{ + int pos; + + if (argc < 2 || (pos = atoi (argv[1])) < 1) + { + audtool_whine_args (argv[0], ""); + exit (1); + } + + return pos; +} + +static char * construct_uri (char * string) +{ + char * filename = g_strdup (string); + char * tmp, * path; + char * uri = NULL; + + // case 1: filename is raw full path or uri + if (filename[0] == '/' || strstr (filename, "://")) + { + uri = g_filename_to_uri (filename, NULL, NULL); + + if (! uri) + uri = g_strdup (filename); + + g_free (filename); + } + // case 2: filename is not raw full path nor uri. + // make full path with pwd. (using g_build_filename) + else + { + path = g_get_current_dir(); + tmp = g_build_filename (path, filename, NULL); + g_free (path); + g_free (filename); + uri = g_filename_to_uri (tmp, NULL, NULL); + g_free (tmp); + } + + return uri; +} + +void playlist_add_url_string (int argc, char * * argv) +{ + char * uri; + + if (argc < 2) + { + audtool_whine_args (argv[0], ""); + exit (1); + } + + uri = construct_uri (argv[1]); + + if (! uri) + exit (1); + + obj_audacious_call_add_sync (dbus_proxy, uri, NULL, NULL); + g_free (uri); +} + +void playlist_delete (int argc, char * * argv) +{ + int pos = check_args_playlist_pos (argc, argv); + obj_audacious_call_delete_sync (dbus_proxy, pos - 1, NULL, NULL); +} + +void playlist_length (int argc, char * * argv) +{ + audtool_report ("%d", get_playlist_length ()); +} + +void playlist_song (int argc, char * * argv) +{ + int pos = check_args_playlist_pos (argc, argv); + char * title = get_entry_title (pos - 1); + audtool_report ("%s", title); + g_free (title); +} + +void number_of_playlists (int argc, char * * argv) +{ + int playlists = 0; + obj_audacious_call_number_of_playlists_sync (dbus_proxy, & playlists, NULL, NULL); + audtool_report ("%d", playlists); +} + +void current_playlist (int argc, char * * argv) +{ + int playlist = -1; + obj_audacious_call_get_active_playlist_sync (dbus_proxy, & playlist, NULL, NULL); + audtool_report ("%d", playlist + 1); +} + +void set_current_playlist (int argc, char * * argv) +{ + if (argc < 2) + { + audtool_whine_args (argv[0], ""); + exit (1); + } + + obj_audacious_call_set_active_playlist_sync (dbus_proxy, atoi (argv[1]) - 1, NULL, NULL); +} + +void playlist_title (int argc, char * * argv) +{ + char * title = NULL; + obj_audacious_call_get_active_playlist_name_sync (dbus_proxy, & title, NULL, NULL); + + if (! title) + exit (1); + + audtool_report ("%s", title); + g_free (title); +} + +void set_playlist_title (int argc, char * * argv) +{ + if (argc < 2) + { + audtool_whine_args (argv[0], ""); + exit (1); + } + + obj_audacious_call_set_active_playlist_name_sync (dbus_proxy, argv[1], NULL, NULL); +} + +void new_playlist (int argc, char * * argv) +{ + obj_audacious_call_new_playlist_sync (dbus_proxy, NULL, NULL); +} + +void delete_current_playlist (int argc, char * * argv) +{ + obj_audacious_call_delete_active_playlist_sync (dbus_proxy, NULL, NULL); +} + +void play_current_playlist (int argc, char * * argv) +{ + obj_audacious_call_play_active_playlist_sync (dbus_proxy, NULL, NULL); +} + +void playlist_song_length (int argc, char * * argv) +{ + int pos = check_args_playlist_pos (argc, argv); + int length = get_entry_length (pos - 1) / 1000; + audtool_report ("%d:%.2d", length / 60, length % 60); +} + +void playlist_song_length_seconds (int argc, char * * argv) +{ + int pos = check_args_playlist_pos (argc, argv); + int length = get_entry_length (pos - 1) / 1000; + audtool_report ("%d", length); +} + +void playlist_song_length_frames (int argc, char * * argv) +{ + int pos = check_args_playlist_pos (argc, argv); + int length = get_entry_length (pos - 1); + audtool_report ("%d", length); +} + +void playlist_display (int argc, char * * argv) +{ + int entries = get_playlist_length (); + + audtool_report ("%d track%s.", entries, entries != 1 ? "s" : ""); + + int total = 0; + + for (int entry = 0; entry < entries; entry ++) + { + char * title = get_entry_title (entry); + int length = get_entry_length (entry) / 1000; + + total += length; + + /* adjust width for multi byte characters */ + int column = 60; + + for (const char * p = title; * p; p = g_utf8_next_char (p)) + { + int stride = g_utf8_next_char (p) - p; + + if (g_unichar_iswide (g_utf8_get_char (p)) || + g_unichar_iswide_cjk (g_utf8_get_char (p))) + column += (stride - 2); + else + column += (stride - 1); + } + + char * fmt = g_strdup_printf ("%%4d | %%-%ds | %%d:%%.2d", column); + audtool_report (fmt, entry + 1, title, length / 60, length % 60); + + g_free (fmt); + g_free (title); + } + + audtool_report ("Total length: %d:%.2d", total / 60, total % 60); +} + +void playlist_position (int argc, char * * argv) +{ + audtool_report ("%d", get_current_entry () + 1); +} + +void playlist_song_filename (int argc, char * * argv) +{ + int pos = check_args_playlist_pos (argc, argv); + char * filename = get_entry_filename (pos - 1); + audtool_report ("%s", filename); + g_free (filename); +} + +void playlist_jump (int argc, char * * argv) +{ + int pos = check_args_playlist_pos (argc, argv); + obj_audacious_call_jump_sync (dbus_proxy, pos - 1, NULL, NULL); +} + +void playlist_clear (int argc, char * * argv) +{ + obj_audacious_call_clear_sync (dbus_proxy, NULL, NULL); +} + +void playlist_repeat_status (int argc, char * * argv) +{ + gboolean repeat = FALSE; + obj_audacious_call_repeat_sync (dbus_proxy, & repeat, NULL, NULL); + audtool_report (repeat ? "on" : "off"); +} + +void playlist_repeat_toggle (int argc, char * * argv) +{ + obj_audacious_call_toggle_repeat_sync (dbus_proxy, NULL, NULL); +} + +void playlist_shuffle_status (int argc, char * * argv) +{ + gboolean shuffle = FALSE; + obj_audacious_call_shuffle_sync (dbus_proxy, & shuffle, NULL, NULL); + audtool_report (shuffle ? "on" : "off"); +} + +void playlist_shuffle_toggle (int argc, char * * argv) +{ + obj_audacious_call_toggle_shuffle_sync (dbus_proxy, NULL, NULL); +} + +void playlist_tuple_field_data (int argc, char * * argv) +{ + int pos; + + if (argc < 3 || (pos = atoi (argv[2])) < 1) + { + audtool_whine_args (argv[0], "<fieldname> <position>"); + audtool_whine_tuple_fields (); + exit (1); + } + + char * str = get_entry_field (pos - 1, argv[1]); + audtool_report ("%s", str); + g_free (str); +} + +void playlist_ins_url_string (int argc, char * * argv) +{ + int pos; + + if (argc < 3 || (pos = atoi (argv[2])) < 1) + { + audtool_whine_args (argv[0], "<url> <position>"); + exit (1); + } + + char * uri = construct_uri (argv[1]); + + if (! uri) + exit (1); + + obj_audacious_call_playlist_ins_url_string_sync (dbus_proxy, uri, pos - 1, NULL, NULL); + + g_free (uri); +} + +void playlist_enqueue_to_temp (int argc, char * * argv) +{ + if (argc < 2) + { + audtool_whine_args (argv[0], "<url>"); + exit (1); + } + + char * uri = construct_uri (argv[1]); + + if (! uri) + exit (1); + + obj_audacious_call_playlist_enqueue_to_temp_sync (dbus_proxy, uri, NULL, NULL); + + g_free (uri); +} diff --git a/src/audtool/handlers_playqueue.c b/src/audtool/handlers_playqueue.c new file mode 100644 index 0000000..56f5196 --- /dev/null +++ b/src/audtool/handlers_playqueue.c @@ -0,0 +1,104 @@ +/* + * handlers_playqueue.c + * Copyright 2005-2013 George Averill, Ariadne Conill, Yoshiki Yazawa, + * Matti Hämäläinen, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stdlib.h> + +#include "audtool.h" +#include "wrappers.h" + +void playqueue_add (int argc, char * * argv) +{ + int pos = check_args_playlist_pos (argc, argv); + obj_audacious_call_playqueue_add_sync (dbus_proxy, pos - 1, NULL, NULL); +} + +void playqueue_remove (int argc, char * * argv) +{ + int pos = check_args_playlist_pos (argc, argv); + obj_audacious_call_playqueue_remove_sync (dbus_proxy, pos - 1, NULL, NULL); +} + +void playqueue_is_queued (int argc, char * * argv) +{ + int pos = check_args_playlist_pos (argc, argv); + find_in_queue (pos - 1); /* calls exit(1) if not found */ + + exit (0); +} + +void playqueue_get_queue_position (int argc, char * * argv) +{ + int pos = check_args_playlist_pos (argc, argv); + audtool_report ("%d", find_in_queue (pos - 1) + 1); +} + +void playqueue_get_list_position (int argc, char * * argv) +{ + int qpos = check_args_playlist_pos (argc, argv); + audtool_report ("%d", get_queue_entry (qpos - 1) + 1); +} + +void playqueue_display (int argc, char * * argv) +{ + int qlength = get_queue_length (); + + audtool_report ("%d queued tracks.", qlength); + + int total = 0; + + for (int qpos = 0; qpos < qlength; qpos ++) + { + int pos = get_queue_entry (qpos); + char * title = get_entry_title (pos); + int length = get_entry_length (pos) / 1000; + + total += length; + + /* adjust width for multi byte characters */ + int column = 60; + + for (const char * p = title; * p; p = g_utf8_next_char (p)) + { + int stride = g_utf8_next_char (p) - p; + + if (g_unichar_iswide (g_utf8_get_char (p)) || + g_unichar_iswide_cjk (g_utf8_get_char (p))) + column += (stride - 2); + else + column += (stride - 1); + } + + char * fmt = g_strdup_printf ("%%4d | %%4d | %%-%ds | %%d:%%.2d", column); + audtool_report (fmt, qpos + 1, pos + 1, title, length / 60, length % 60); + g_free (fmt); + } + + audtool_report ("Total length: %d:%.2d", total / 60, total % 60); +} + +void playqueue_length (int argc, char * * argv) +{ + audtool_report ("%d", get_queue_length ()); +} + +void playqueue_clear (int argc, char * * argv) +{ + obj_audacious_call_playqueue_clear_sync (dbus_proxy, NULL, NULL); +} diff --git a/src/audtool/handlers_vitals.c b/src/audtool/handlers_vitals.c new file mode 100644 index 0000000..76f0eb3 --- /dev/null +++ b/src/audtool/handlers_vitals.c @@ -0,0 +1,129 @@ +/* + * handlers_vitals.c + * Copyright 2005-2013 George Averill, Ariadne Conill, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stdlib.h> + +#include "audtool.h" +#include "wrappers.h" + +void get_current_song (int argc, char * * argv) +{ + char * title = get_entry_title (get_current_entry ()); + audtool_report ("%s", title); + g_free (title); +} + +void get_current_song_filename (int argc, char * * argv) +{ + char * filename = get_entry_filename (get_current_entry ()); + audtool_report ("%s", filename); + g_free (filename); +} + +void get_current_song_output_length (int argc, char * * argv) +{ + int time = get_current_time () / 1000; + audtool_report ("%d:%.2d", time / 60, time % 60); +} + +void get_current_song_output_length_seconds (int argc, char * * argv) +{ + int time = get_current_time () / 1000; + audtool_report ("%d", time); +} + +void get_current_song_output_length_frames (int argc, char * * argv) +{ + int time = get_current_time (); + audtool_report ("%d", time); +} + +void get_current_song_length (int argc, char * * argv) +{ + int length = get_entry_length (get_current_entry ()) / 1000; + audtool_report ("%d:%.2d", length / 60, length % 60); +} + +void get_current_song_length_seconds (int argc, char * * argv) +{ + int length = get_entry_length (get_current_entry ()) / 1000; + audtool_report ("%d", length); +} + +void get_current_song_length_frames (int argc, char * * argv) +{ + int length = get_entry_length (get_current_entry ()); + audtool_report ("%d", length); +} + +void get_current_song_bitrate (int argc, char * * argv) +{ + int bitrate; + get_current_info (& bitrate, NULL, NULL); + audtool_report ("%d", bitrate); +} + +void get_current_song_bitrate_kbps (int argc, char * * argv) +{ + int bitrate; + get_current_info (& bitrate, NULL, NULL); + audtool_report ("%d", bitrate / 1000); +} + +void get_current_song_frequency (int argc, char * * argv) +{ + int samplerate; + get_current_info (NULL, & samplerate, NULL); + audtool_report ("%d", samplerate); +} + +void get_current_song_frequency_khz (int argc, char * * argv) +{ + int samplerate; + get_current_info (NULL, & samplerate, NULL); + audtool_report ("%d", samplerate / 1000); +} + +void get_current_song_channels (int argc, char * * argv) +{ + int channels; + get_current_info (NULL, NULL, & channels); + audtool_report ("%d", channels); +} + +void get_current_song_tuple_field_data (int argc, char * * argv) +{ + if (argc < 2) + { + audtool_whine_args (argv[0], "<fieldname>"); + audtool_whine_tuple_fields(); + exit (1); + } + + char * str = get_entry_field (get_current_entry (), argv[1]); + audtool_report ("%s", str); + g_free (str); +} + +void get_current_song_info (int argc, char * * argv) +{ + int bitrate, samplerate, channels; + get_current_info (& bitrate, & samplerate, & channels); + audtool_report ("rate = %d freq = %d nch = %d", bitrate, samplerate, channels); +} diff --git a/src/audtool/main.c b/src/audtool/main.c new file mode 100644 index 0000000..5584ed3 --- /dev/null +++ b/src/audtool/main.c @@ -0,0 +1,275 @@ +/* + * main.c + * Copyright 2005-2013 George Averill, Ariadne Conill, Yoshiki Yazawa, and + * John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <locale.h> + +#ifdef _WIN32 +#include <windows.h> +#endif + +#include "audtool.h" + +const struct commandhandler handlers[] = +{ + {"<sep>", NULL, "Current song information", 0}, + {"current-song", get_current_song, "print formatted song title", 0}, + {"current-song-filename", get_current_song_filename, "print song file name", 0}, + {"current-song-length", get_current_song_length, "print song length", 0}, + {"current-song-length-seconds", get_current_song_length_seconds, "print song length in seconds", 0}, + {"current-song-length-frames", get_current_song_length_frames, "print song length in milliseconds", 0}, + {"current-song-output-length", get_current_song_output_length, "print playback time", 0}, + {"current-song-output-length-seconds", get_current_song_output_length_seconds, "print playback time in seconds", 0}, + {"current-song-output-length-frames", get_current_song_output_length_frames, "print playback time in milliseconds", 0}, + {"current-song-bitrate", get_current_song_bitrate, "print bitrate in bits per second", 0}, + {"current-song-bitrate-kbps", get_current_song_bitrate_kbps, "print bitrate in kilobits per second", 0}, + {"current-song-frequency", get_current_song_frequency, "print sampling rate in hertz", 0}, + {"current-song-frequency-khz", get_current_song_frequency_khz, "print sampling rate in kilohertz", 0}, + {"current-song-channels", get_current_song_channels, "print number of channels", 0}, + {"current-song-tuple-data", get_current_song_tuple_field_data, "print value of named field", 1}, + {"current-song-info", get_current_song_info, "print bitrate, sampling rate, and channels", 0}, + + {"<sep>", NULL, "Playback commands", 0}, + {"playback-play", playback_play, "start/restart/unpause playback", 0}, + {"playback-pause", playback_pause, "pause/unpause playback", 0}, + {"playback-playpause", playback_playpause, "start/pause/unpause playback", 0}, + {"playback-stop", playback_stop, "stop playback", 0}, + {"playback-playing", playback_playing, "exit code = 0 if playing", 0}, + {"playback-paused", playback_paused, "exit code = 0 if paused", 0}, + {"playback-stopped", playback_stopped, "exit code = 0 if not playing", 0}, + {"playback-status", playback_status, "print status (playing/paused/stopped)", 0}, + {"playback-seek", playback_seek, "seek to given time", 1}, + {"playback-seek-relative", playback_seek_relative, "seek to relative time offset", 1}, + {"playback-record", playback_record, "toggle stream recording", 0}, + {"playback-recording", playback_recording, "exit code = 0 if recording", 0}, + + {"<sep>", NULL, "Playlist commands", 0}, + {"select-displayed", select_displayed, "apply commands to displayed playlist", 0}, + {"select-playing", select_playing, "apply commands to playing playlist", 0}, + {"playlist-advance", playlist_advance, "skip to next song", 0}, + {"playlist-advance-album", playlist_advance_album, "skip to next album", 0}, + {"playlist-reverse", playlist_reverse, "skip to previous song", 0}, + {"playlist-reverse-album", playlist_reverse_album, "skip to beginning of the previous album", 0}, + {"playlist-addurl", playlist_add_url_string, "add URI at end of playlist", 1}, + {"playlist-insurl", playlist_ins_url_string, "insert URI at given position", 2}, + {"playlist-addurl-to-new-playlist", playlist_enqueue_to_temp, "open URI in \"Now Playing\" playlist", 1}, + {"playlist-delete", playlist_delete, "remove song at given position", 1}, + {"playlist-length", playlist_length, "print number of songs in playlist", 0}, + {"playlist-song", playlist_song, "print formatted title of given song", 1}, + {"playlist-song-filename", playlist_song_filename, "print file name of given song", 1}, + {"playlist-song-length", playlist_song_length, "print length of given song", 1}, + {"playlist-song-length-seconds", playlist_song_length_seconds, "print length of given song in seconds", 1}, + {"playlist-song-length-frames", playlist_song_length_frames, "print length of given song in milliseconds", 1}, + {"playlist-tuple-data", playlist_tuple_field_data, "print value of named field for given song", 2}, + {"playlist-display", playlist_display, "print all songs in playlist", 0}, + {"playlist-position", playlist_position, "print position of current song", 0}, + {"playlist-jump", playlist_jump, "skip to given song", 1}, + {"playlist-clear", playlist_clear, "clear playlist", 0}, + {"playlist-auto-advance-status", playlist_auto_advance_status, "query playlist auto-advance", 0}, + {"playlist-auto-advance-toggle", playlist_auto_advance_toggle, "toggle playlist auto-advance", 0}, + {"playlist-repeat-status", playlist_repeat_status, "query playlist repeat", 0}, + {"playlist-repeat-toggle", playlist_repeat_toggle, "toggle playlist repeat", 0}, + {"playlist-shuffle-status", playlist_shuffle_status, "query playlist shuffle", 0}, + {"playlist-shuffle-toggle", playlist_shuffle_toggle, "toggle playlist shuffle", 0}, + {"playlist-stop-after-status", playlist_stop_after_status, "query if stopping after current song", 0}, + {"playlist-stop-after-toggle", playlist_stop_after_toggle, "toggle if stopping after current song", 0}, + + {"<sep>", NULL, "More playlist commands", 0}, + {"number-of-playlists", number_of_playlists, "print number of playlists", 0}, + {"current-playlist", current_playlist, "print number of current playlist", 0}, + {"play-current-playlist", play_current_playlist, "play/resume current playlist", 0}, + {"set-current-playlist", set_current_playlist, "make given playlist current", 1}, + {"current-playlist-name", playlist_title, "print current playlist title", 0}, + {"set-current-playlist-name", set_playlist_title, "set current playlist title", 1}, + {"new-playlist", new_playlist, "insert new playlist", 0}, + {"delete-current-playlist", delete_current_playlist, "remove current playlist", 0}, + + {"<sep>", NULL, "Playlist queue commands", 0}, + {"playqueue-add", playqueue_add, "add given song to queue", 1}, + {"playqueue-remove", playqueue_remove, "remove given song from queue", 1}, + {"playqueue-is-queued", playqueue_is_queued, "exit code = 0 if given song is queued", 1}, + {"playqueue-get-queue-position", playqueue_get_queue_position, "print queue position of given song", 1}, + {"playqueue-get-list-position", playqueue_get_list_position, "print n-th queued song", 1}, + {"playqueue-length", playqueue_length, "print number of songs in queue", 0}, + {"playqueue-display", playqueue_display, "print all songs in queue", 0}, + {"playqueue-clear", playqueue_clear, "clear queue", 0}, + + {"<sep>", NULL, "Volume control and equalizer", 0}, + {"get-volume", get_volume, "print current volume level in percent", 0}, + {"set-volume", set_volume, "set current volume level in percent", 1}, + {"equalizer-activate", equalizer_active, "activate/deactivate equalizer", 1}, + {"equalizer-get", equalizer_get_eq, "print equalizer settings", 0}, + {"equalizer-set", equalizer_set_eq, "set equalizer settings", 11}, + {"equalizer-get-preamp", equalizer_get_eq_preamp, "print equalizer pre-amplification", 0}, + {"equalizer-set-preamp", equalizer_set_eq_preamp, "set equalizer pre-amplification", 1}, + {"equalizer-get-band", equalizer_get_eq_band, "print gain of given equalizer band", 1}, + {"equalizer-set-band", equalizer_set_eq_band, "set gain of given equalizer band", 2}, + + {"<sep>", NULL, "Miscellaneous", 0}, + {"mainwin-show", mainwin_show, "show/hide Audacious", 1}, + {"filebrowser-show", show_filebrowser, "show/hide Add Files window", 1}, + {"jumptofile-show", show_jtf_window, "show/hide Jump to Song window", 1}, + {"preferences-show", show_preferences_window, "show/hide Settings window", 1}, + {"about-show", show_about_window, "show/hide About window", 1}, + + {"version", get_version, "print Audacious version", 0}, + {"plugin-is-enabled", plugin_is_enabled, "exit code = 0 if plugin is enabled", 1}, + {"plugin-enable", plugin_enable, "enable/disable plugin", 2}, + {"config-get", config_get, "DO NOT USE", 1}, + {"config-set", config_set, "DO NOT USE", 2}, + {"shutdown", shutdown_audacious_server, "shut down Audacious", 0}, + + {"help", get_handlers_list, "print this help", 0}, + + {NULL, NULL, NULL, 0} +}; + +ObjAudacious * dbus_proxy = NULL; +static GDBusConnection * connection = NULL; + +static void audtool_disconnect (void) +{ + g_object_unref (dbus_proxy); + dbus_proxy = NULL; + + g_dbus_connection_close_sync (connection, NULL, NULL); + connection = NULL; +} + +static void audtool_connect (int instance) +{ + GError * error = NULL; + + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, & error); + + if (! connection) + { + fprintf (stderr, "D-Bus error: %s\n", error->message); + g_error_free (error); + exit (EXIT_FAILURE); + } + + char name[32]; + if (instance == 1) + strcpy (name, "org.atheme.audacious"); + else + sprintf (name, "org.atheme.audacious-%d", instance); + + dbus_proxy = obj_audacious_proxy_new_sync (connection, 0, name, + "/org/atheme/audacious", NULL, & error); + + if (! dbus_proxy) + { + fprintf (stderr, "D-Bus error: %s\n", error->message); + g_error_free (error); + g_dbus_connection_close_sync (connection, NULL, NULL); + exit (EXIT_FAILURE); + } + + atexit (audtool_disconnect); +} + +#ifdef _WIN32 +static void print_utf8 (const char * str) +{ + HANDLE h = GetStdHandle (STD_OUTPUT_HANDLE); + DWORD mode; + + if (h != INVALID_HANDLE_VALUE && GetConsoleMode (h, & mode)) + { + // stdout is the console, which needs special handling to display + // non-ASCII characters correctly (in 2018, the MS runtime *still* + // doesn't handle UTF-8 reliably). + glong n_converted; + gunichar2 * utf16 = g_utf8_to_utf16 (str, -1, NULL, & n_converted, NULL); + + if (utf16) + { + DWORD n_written; + WriteConsoleW (h, utf16, n_converted, & n_written, NULL); + g_free (utf16); + } + } + else + { + // fputs() works fine when stdout is redirected. + fputs (str, stdout); + } +} +#endif // _WIN32 + +int main (int argc, char * * argv) +{ + int instance = 1; + int i, j, k = 0; + + setlocale (LC_CTYPE, ""); + + g_type_init(); + +#ifdef _WIN32 + g_set_print_handler (print_utf8); +#endif + + // parse instance number (must come first) + if (argc >= 2 && argv[1][0] == '-' && argv[1][1] >= '1' && argv[1][1] <= '9' && ! argv[1][2]) + { + instance = argv[1][1] - '0'; + argc --; + argv ++; + } + + audtool_connect (instance); + + if (argc < 2) + { + fprintf (stderr, "Not enough parameters. Try \"audtool help\".\n"); + exit (EXIT_FAILURE); + } + + for (j = 1; j < argc; j ++) + { + for (i = 0; handlers[i].name != NULL; i++) + { + if ((! g_ascii_strcasecmp (handlers[i].name, argv[j]) || + ! g_ascii_strcasecmp (g_strconcat ("--", handlers[i].name, NULL), + argv[j])) && g_ascii_strcasecmp ("<sep>", handlers[i].name)) + { + int numargs = MIN (handlers[i].args + 1, argc - j); + handlers[i].handler (numargs, & argv[j]); + j += handlers[i].args; + k ++; + + if (j >= argc) + break; + } + } + } + + if (k == 0) + { + fprintf (stderr, "Unknown command \"%s\". Try \"audtool help\".\n", argv[1]); + exit (EXIT_FAILURE); + } + + return 0; +} diff --git a/src/audtool/meson.build b/src/audtool/meson.build new file mode 100644 index 0000000..df7539f --- /dev/null +++ b/src/audtool/meson.build @@ -0,0 +1,23 @@ +audtool_sources = [ + 'main.c', + 'handlers_general.c', + 'handlers_playback.c', + 'handlers_playlist.c', + 'handlers_playqueue.c', + 'handlers_vitals.c', + 'handlers_equalizer.c', + 'report.c', + 'wrappers.c' +] + + +audtool_deps = aud_dbus_deps + + +audtool_exe = executable('audtool', + audtool_sources, + link_with: aud_dbus_lib, + dependencies: audtool_deps, + include_directories: aud_dbus_inc, + install: true +) diff --git a/src/audtool/report.c b/src/audtool/report.c new file mode 100644 index 0000000..0628756 --- /dev/null +++ b/src/audtool/report.c @@ -0,0 +1,101 @@ +/* + * report.c + * Copyright 2007-2008 Ariadne Conill and Matti Hämäläinen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stdlib.h> + +#include "audtool.h" + +void audtool_report (const char * str, ...) +{ + char * buf; + va_list va; + + va_start (va, str); + buf = g_strdup_vprintf (str, va); + va_end (va); + + g_print ("%s\n", buf); + g_free (buf); +} + +void audtool_whine (const char * str, ...) +{ + char * buf; + va_list va; + + va_start (va, str); + buf = g_strdup_vprintf (str, va); + va_end (va); + + g_printerr ("audtool: %s", buf); + g_free (buf); +} + +void audtool_whine_args (const char * name, const char * fmt, ...) +{ + char * buf; + va_list va; + + va_start (va, fmt); + buf = g_strdup_vprintf (fmt, va); + va_end (va); + + g_printerr ("audtool: Invalid parameters for %s\n", name); + g_printerr (" syntax: %s %s\n", name, buf); + g_free (buf); +} + +void audtool_whine_tuple_fields (void) +{ + char * * fields = NULL; + obj_audacious_call_get_tuple_fields_sync (dbus_proxy, & fields, NULL, NULL); + + if (! fields) + exit (1); + + audtool_whine ("Field names include:\n"); + + char * * tmp = fields; + int col = 0; + + g_printerr (" "); + + while (* tmp) + { + col += g_utf8_strlen (* tmp, -1); + + if (col > 45) + { + g_printerr ("\n "); + col = 0; + } + + g_printerr ("%s", * tmp); + + g_free (* tmp); + tmp ++; + + if (* tmp) + g_printerr (", "); + } + + g_printerr ("\n"); + + g_free (fields); +} diff --git a/src/audtool/wrappers.c b/src/audtool/wrappers.c new file mode 100644 index 0000000..35afa35 --- /dev/null +++ b/src/audtool/wrappers.c @@ -0,0 +1,193 @@ +/* + * wrappers.c + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stdlib.h> + +#include "audtool.h" +#include "wrappers.h" + +void generic_on_off (int argc, char * * argv, OnOffFunc func) +{ + gboolean show; + + if (argc == 1) + show = TRUE; + else if (argc == 2 && ! g_ascii_strcasecmp (argv[1], "on")) + show = TRUE; + else if (argc == 2 && ! g_ascii_strcasecmp (argv[1], "off")) + show = FALSE; + else + { + audtool_whine_args (argv[0], "<on/off>"); + exit (1); + } + + func (dbus_proxy, show, NULL, NULL); +} + +int get_playlist_length (void) +{ + int length = -1; + obj_audacious_call_length_sync (dbus_proxy, & length, NULL, NULL); + + if (length < 0) + exit (1); + + return length; +} + +int get_queue_length (void) +{ + int length = -1; + obj_audacious_call_get_playqueue_length_sync (dbus_proxy, & length, NULL, NULL); + + if (length < 0) + exit (1); + + return length; +} + +int get_queue_entry (int qpos) +{ + unsigned entry = -1; + obj_audacious_call_queue_get_list_pos_sync (dbus_proxy, qpos, & entry, NULL, NULL); + + if (entry == (unsigned) -1) + exit (1); + + return entry; +} + +int find_in_queue (int entry) +{ + unsigned qpos = -1; + obj_audacious_call_queue_get_queue_pos_sync (dbus_proxy, entry, & qpos, NULL, NULL); + + if (qpos == (unsigned) -1) + exit (1); + + return qpos; +} + +int get_current_entry (void) +{ + unsigned entry = -1; + obj_audacious_call_position_sync (dbus_proxy, & entry, NULL, NULL); + + if (entry == (unsigned) -1) + exit (1); + + return entry; +} + +char * get_entry_filename (int entry) +{ + char * uri = NULL; + obj_audacious_call_song_filename_sync (dbus_proxy, entry, & uri, NULL, NULL); + + if (! uri) + exit (1); + + char * filename = g_filename_from_uri (uri, NULL, NULL); + + if (filename) + { + g_free (uri); + return filename; + } + + return uri; +} + +char * get_entry_title (int entry) +{ + char * title = NULL; + obj_audacious_call_song_title_sync (dbus_proxy, entry, & title, NULL, NULL); + + if (! title) + exit (1); + + return title; +} + +int get_entry_length (int entry) +{ + int length = -1; + obj_audacious_call_song_frames_sync (dbus_proxy, entry, & length, NULL, NULL); + + if (length < 0) + exit (1); + + return length; +} + +char * get_entry_field (int entry, const char * field) +{ + GVariant * var = NULL; + obj_audacious_call_song_tuple_sync (dbus_proxy, entry, field, & var, NULL, NULL); + + if (! var || ! g_variant_is_of_type (var, G_VARIANT_TYPE_VARIANT)) + exit (1); + + GVariant * var2 = g_variant_get_variant (var); + + if (! var2) + exit (1); + + char * str; + + if (g_variant_is_of_type (var2, G_VARIANT_TYPE_STRING)) + str = g_strdup (g_variant_get_string (var2, NULL)); + else if (g_variant_is_of_type (var2, G_VARIANT_TYPE_INT32)) + str = g_strdup_printf ("%d", (int) g_variant_get_int32 (var2)); + else + exit (1); + + g_variant_unref (var); + g_variant_unref (var2); + + return str; +} + +int get_current_time (void) +{ + unsigned time = -1; + obj_audacious_call_time_sync (dbus_proxy, & time, NULL, NULL); + + if (time == (unsigned) -1) + exit (1); + + return time; +} + +void get_current_info (int * bitrate_p, int * samplerate_p, int * channels_p) +{ + int bitrate = -1, samplerate = -1, channels = -1; + obj_audacious_call_get_info_sync (dbus_proxy, & bitrate, & samplerate, & channels, NULL, NULL); + + if (bitrate < 0 || samplerate < 0 || channels < 0) + exit (1); + + if (bitrate_p) + * bitrate_p = bitrate; + if (samplerate_p) + * samplerate_p = samplerate; + if (channels_p) + * channels_p = channels; +} diff --git a/src/audtool/wrappers.h b/src/audtool/wrappers.h new file mode 100644 index 0000000..e9a9659 --- /dev/null +++ b/src/audtool/wrappers.h @@ -0,0 +1,43 @@ +/* + * wrappers.h + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef AUDTOOL_WRAPPERS_H +#define AUDTOOL_WRAPPERS_H + +typedef gboolean (* OnOffFunc) (ObjAudacious * proxy, gboolean show, + GCancellable * cancellable, GError * * error); + +void generic_on_off (int argc, char * * argv, OnOffFunc func); + +int get_playlist_length (void); + +int get_queue_length (void); +int get_queue_entry (int qpos); +int find_in_queue (int entry); + +int get_current_entry (void); +char * get_entry_filename (int entry); +char * get_entry_title (int entry); +int get_entry_length (int entry); +char * get_entry_field (int entry, const char * field); + +int get_current_time (void); +void get_current_info (int * bitrate, int * samplerate, int * channels); + +#endif /* AUDTOOL_WRAPPERS_H */ diff --git a/src/config.h.meson b/src/config.h.meson new file mode 100644 index 0000000..51b89ff --- /dev/null +++ b/src/config.h.meson @@ -0,0 +1,21 @@ +#mesondefine PACKAGE +#mesondefine BUILDSTAMP +#mesondefine VERSION +#mesondefine COPYRIGHT +#mesondefine EXPORT +#mesondefine PLUGIN_SUFFIX + +#define PACKAGE_VERSION VERSION +#define ICONV_CONST + +#mesondefine INSTALL_BINDIR +#mesondefine INSTALL_DATADIR +#mesondefine INSTALL_PLUGINDIR +#mesondefine INSTALL_LOCALEDIR +#mesondefine INSTALL_DESKTOPFILE +#mesondefine INSTALL_ICONFILE + +#mesondefine USE_DBUS +#mesondefine USE_QT + +#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_32 diff --git a/src/dbus/Makefile b/src/dbus/Makefile new file mode 100644 index 0000000..45a7e46 --- /dev/null +++ b/src/dbus/Makefile @@ -0,0 +1,18 @@ +STATIC_LIB_NOINST = aud-dbus.a + +SRCS = aud-dbus.c +CLEAN = aud-dbus.c aud-dbus.h + +include ../../buildsys.mk +include ../../extra.mk + +CPPFLAGS := -I../.. ${CPPFLAGS} ${GLIB_CFLAGS} ${GIO_CFLAGS} +LIBS := ${LIBS} ${GLIB_LIBS} ${GIO_LIBS} + +pre-depend: aud-dbus.c aud-dbus.h + +aud-dbus.h: aud-dbus.xml + gdbus-codegen --interface-prefix org.atheme. --c-namespace Obj --generate-c-code aud-dbus aud-dbus.xml + +aud-dbus.c: aud-dbus.h + # nothing to do here diff --git a/src/dbus/aud-dbus.xml b/src/dbus/aud-dbus.xml new file mode 100644 index 0000000..b240d90 --- /dev/null +++ b/src/dbus/aud-dbus.xml @@ -0,0 +1,468 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<!-- + * aud-dbus.xml + * Copyright 2007-2016 Ben Tucker, Yoshiki Yazawa, Matti Hämäläinen, and + * John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + --> + +<node name="/"> + <interface name="org.atheme.audacious"> + + <!-- General Commands --> + <!-- ++++++++++++++++ --> + + <!-- Audacious version --> + <method name="Version"> + <arg type="s" direction="out" name="version"/> + </method> + + <method name="PluginIsEnabled"> + <arg type="s" direction="in" name="plugin" /> + <arg type="b" direction="out" name="enabled" /> + </method> + + <method name="PluginEnable"> + <arg type="s" direction="in" name="plugin" /> + <arg type="b" direction="in" name="enable" /> + </method> + + <method name="ConfigGet"> + <arg type="s" direction="in" name="section" /> + <arg type="s" direction="in" name="name" /> + <arg type="s" direction="out" name="value" /> + </method> + + <method name="ConfigSet"> + <arg type="s" direction="in" name="section" /> + <arg type="s" direction="in" name="name" /> + <arg type="s" direction="in" name="value" /> + </method> + + <!-- Quit Audacious --> + <method name="Quit" /> + + <!-- Show "Add Files" dialog --> + <method name="ShowFilebrowser"> + <arg type="b" direction="in" name="show"/> + </method> + + <!-- Show "Open Files" dialog --> + <!-- (same as "eject" button in a Winamp skin) --> + <method name="Eject" /> + + <!-- Main window visibility --> + <method name="MainWinVisible"> + <arg type="b" direction="out" name="is_main_win"/> + </method> + + <!-- Toggle main window visibility --> + <method name="ShowMainWin"> + <arg type="b" direction="in" name="show"/> + </method> + + <!-- Show preferences window --> + <method name="ShowPrefsBox"> + <arg type="b" direction="in" name="show"/> + </method> + + <!-- Show about window --> + <method name="ShowAboutBox"> + <arg type="b" direction="in" name="show"/> + </method> + + <!-- Show jump to file window --> + <method name="ShowJtfBox"> + <arg type="b" direction="in" name="show"/> + </method> + + <!-- Send startup notification --> + <method name="StartupNotify"> + <arg type="s" direction="in" name="id"/> + </method> + + <!-- Get names of available 'standard' tuple fields --> + <method name="GetTupleFields"> + <!-- Return array of tuple field names --> + <arg type="as" direction="out" name="fields"/> + </method> + + <!-- Playback Information/Manipulation --> + <!-- +++++++++++++++++++++++++++++++++ --> + + <!-- Begin or resume playback --> + <method name="Play" /> + + <!-- Pause playback --> + <method name="Pause" /> + + <!-- Either play or pause --> + <method name="PlayPause" /> + + <!-- Stop playback --> + <method name="Stop" /> + + <!-- Is playback playing? --> + <method name="Playing"> + <!-- Return true if playing, false otherwise --> + <arg type="b" direction="out" name="is_playing"/> + </method> + + <!-- Is playback paused? --> + <method name="Paused"> + <!-- Return true if paused, false otherwise --> + <arg type="b" direction="out" name="is_paused"/> + </method> + + <!-- Is playback stopped? --> + <method name="Stopped"> + <!-- Return true if stopped, false otherwise --> + <arg type="b" direction="out" name="is_stopped"/> + </method> + + <!-- What is the playback status? --> + <method name="Status"> + <!-- Return the status as a string: --> + <!-- one of {"playing" "paused" "stopped"} --> + <arg type="s" direction="out" name="status"/> + </method> + + <!-- Toggle recording of stream --> + <method name="Record" /> + + <!-- Is stream recording enabled? --> + <method name="Recording"> + <arg type="b" direction="out" name="is_recording"/> + </method> + + <!-- What is the bitrate, frequency, and number of channels of the --> + <!-- current audio format? ("Info" and "GetInfo" are synonymous) --> + <method name="Info"> + <arg type="i" direction="out" name="rate"/> + <arg type="i" direction="out" name="freq"/> + <arg type="i" direction="out" name="nch"/> + </method> + <method name="GetInfo"> + <arg type="i" direction="out" name="rate"/> + <arg type="i" direction="out" name="freq"/> + <arg type="i" direction="out" name="nch"/> + </method> + + <!-- What is the current output position? --> + <method name="Time"> + <!-- Position of song, in ms --> + <arg type="u" direction="out" name="time"/> + </method> + + <!-- Seek to some absolute position in the current song --> + <method name="Seek"> + <!-- Position of song, in ms, to seek to --> + <arg type="u" direction="in" name="pos"/> + </method> + + <!-- Volume and Equalizer --> + <!-- ++++++++++++++++++++ --> + + <!-- What is the playback volume? --> + <method name="Volume"> + <!-- Volume of the left channel --> + <arg type="i" direction="out" name="vl"/> + <!-- Volume of the right channel --> + <arg type="i" direction="out" name="vr"/> + </method> + + <!-- Set the playback volume --> + <method name="SetVolume"> + <!-- Volume of the left channel --> + <arg type="i" direction="in" name="vl"/> + <!-- Volume of the right channel --> + <arg type="i" direction="in" name="vr"/> + </method> + + <!-- Get the playback balance --> + <method name="Balance"> + <!-- Balance between left and right channels --> + <arg type="i" direction="out" name="balance"/> + </method> + + <!-- equalizer --> + <method name="GetEq"> + <arg type="d" direction="out" name="preamp"/> + <arg type="ad" direction="out" name="bands"/> + </method> + + <method name="GetEqPreamp"> + <arg type="d" direction="out" name="preamp"/> + </method> + + <method name="GetEqBand"> + <arg type="i" direction="in" name="band"/> + <arg type="d" direction="out" name="value"/> + </method> + + <method name="SetEq"> + <arg type="d" direction="in" name="preamp"/> + <arg type="ad" direction="in" name="bands"/> + </method> + + <method name="SetEqPreamp"> + <arg type="d" direction="in" name="preamp"/> + </method> + + <method name="SetEqBand"> + <arg type="i" direction="in" name="band"/> + <arg type="d" direction="in" name="value"/> + </method> + + <!-- Activate/Deactivate Equalizer --> + <method name="EqualizerActivate"> + <arg type="b" direction="in" name="active"/> + </method> + + <!-- Playlist Information/Manipulation --> + <!-- +++++++++++++++++++++++++++++++++ --> + + <!-- Select playlist to control --> + <method name="SelectDisplayedPlaylist"/> + <method name="SelectPlayingPlaylist"/> + + <!-- Playlist position --> + <method name="Position"> + <!-- Return position of current song in current playlist --> + <arg type="u" direction="out" name="pos"/> + </method> + + <!-- Skip ahead one song in the current playlist --> + <method name="Advance" /> + + <!-- Skip ahead one album in the current playlist --> + <method name="AdvanceAlbum" /> + + <!-- Skip backwards one song in the current playlist --> + <method name="Reverse" /> + + <!-- Skip backwards one album in the current playlist --> + <method name="ReverseAlbum" /> + + <!-- Playlist length --> + <method name="Length"> + <!-- Return length of current playlist --> + <arg type="i" direction="out" name="length"/> + </method> + + <!-- Get a song's title --> + <method name="SongTitle"> + <!-- Song position in the playlist --> + <arg type="u" direction="in" name="pos"/> + + <!-- Return title of desired song --> + <arg type="s" direction="out" name="title"/> + </method> + + <!-- Get a song's filename --> + <method name="SongFilename"> + <!-- Song position in the playlist --> + <arg type="u" direction="in" name="pos"/> + + <!-- Return filename of desired song --> + <arg type="s" direction="out" name="filename"/> + </method> + + <!-- Get the length of some song, in seconds --> + <method name="SongLength"> + <!-- Song position in the playlist --> + <arg type="u" direction="in" name="pos"/> + + <!-- Return length, in seconds, of desired song --> + <arg type="i" direction="out" name="length"/> + </method> + + <!-- Get the length of some song, in frames --> + <method name="SongFrames"> + <!-- Song position in the playlist --> + <arg type="u" direction="in" name="pos"/> + + <!-- Return length, in frames, of desired song --> + <arg type="i" direction="out" name="length"/> + </method> + + <!-- Get the value of a tuple field of some song --> + <method name="SongTuple"> + <!-- Song position in the playlist --> + <arg type="u" direction="in" name="pos"/> + + <!-- Tuple name --> + <arg type="s" direction="in" name="tuple"/> + + <!-- Return tuple value --> + <arg type="v" direction="out" name="value"/> + </method> + + <!-- Jump to some position in the playlist --> + <method name="Jump"> + <!-- Song position to jump to --> + <arg type="u" direction="in" name="pos"/> + </method> + + <!-- Add (append) a file to the current playlist --> + <!-- ("Add", "AddUrl", and "PlaylistAdd" are synonymous) --> + <method name="Add"> + <!-- URI of file to add --> + <arg type="s" direction="in" name="file"/> + </method> + <method name="AddUrl"> + <arg type="s" direction="in" name="url"/> + </method> + <method name="PlaylistAdd"> + <arg type="s" direction="in" name="list"/> + </method> + + <!-- Insert a file at the given position in the playlist --> + <method name="PlaylistInsUrlString"> + <arg type="s" direction="in" name="url"/> + <arg type="i" direction="in" name="pos"/> + </method> + + <!-- Add a list of files --> + <method name="AddList"> + <!-- Array of filenames to add --> + <arg type="as" direction="in" name="filenames"/> + </method> + + <!-- Open a list of files --> + <method name="OpenList"> + <!-- Array of filenames to open --> + <arg type="as" direction="in" name="filenames"/> + </method> + + <!-- Open a file in a temporary playlist --> + <method name="PlaylistEnqueueToTemp"> + <arg type="s" direction="in" name="url"/> + </method> + + <!-- Open a list of files in a temporary playlist --> + <method name="OpenListToTemp"> + <!-- Array of filenames to open --> + <arg type="as" direction="in" name="filenames"/> + </method> + + <!-- Delete some song from the playlist --> + <method name="Delete"> + <!-- Position of song to delete --> + <arg type="u" direction="in" name="pos"/> + </method> + + <!-- Clear the playlist --> + <method name="Clear" /> + + <!-- Query auto-advance status --> + <method name="AutoAdvance"> + <arg type="b" direction="out" name="is_advance"/> + </method> + + <!-- Toggle auto-advance --> + <method name="ToggleAutoAdvance" /> + + <!-- Query repeat status --> + <method name="Repeat"> + <arg type="b" direction="out" name="is_repeat"/> + </method> + + <!-- Toggle repeat --> + <method name="ToggleRepeat" /> + + <!-- Query shuffle status --> + <method name="Shuffle"> + <arg type="b" direction="out" name="is_shuffle"/> + </method> + + <!-- Toggle shuffle --> + <method name="ToggleShuffle" /> + + <!-- Query stop-after-song status --> + <method name="StopAfter"> + <arg type="b" direction="out" name="is_stopping"/> + </method> + + <!-- Toggle stop-after-song --> + <method name="ToggleStopAfter" /> + + <!-- Playlist Queue --> + <!-- ++++++++++++++ --> + + <!-- Playqueue get playlist pos --> + <method name="QueueGetListPos"> + <arg type="u" direction="in" name="qpos"/> + <arg type="u" direction="out" name="pos"/> + </method> + + <!-- Playqueue get playqueue pos --> + <method name="QueueGetQueuePos"> + <arg type="u" direction="in" name="pos"/> + <arg type="u" direction="out" name="qpos"/> + </method> + + <method name="GetPlayqueueLength"> + <arg type="i" direction="out" name="length"/> + </method> + + <method name="PlayqueueAdd"> + <arg type="i" direction="in" name="pos"/> + </method> + + <method name="PlayqueueRemove"> + <arg type="i" direction="in" name="pos"/> + </method> + + <method name="PlayqueueClear" /> + + <method name="PlayqueueIsQueued"> + <arg type="i" direction="in" name="pos"/> + <arg type="b" direction="out" name="is_queued"/> + </method> + + <!-- Add/Remove/Switch Playlists --> + <!-- +++++++++++++++++++++++++++ --> + + <method name="NumberOfPlaylists"> + <arg type="i" direction="out" name="count" /> + </method> + + <method name="GetActivePlaylist"> + <arg type="i" direction="out" name="plnum" /> + </method> + + <method name="SetActivePlaylist"> + <arg type="i" direction="in" name="plnum" /> + </method> + + <method name="GetActivePlaylistName"> + <arg type="s" direction="out" name="plname" /> + </method> + + <method name="SetActivePlaylistName"> + <arg type="s" direction="in" name="plname" /> + </method> + + <method name="NewPlaylist" /> + + <method name="DeleteActivePlaylist" /> + + <method name="PlayActivePlaylist" /> + + </interface> +</node> diff --git a/src/dbus/meson.build b/src/dbus/meson.build new file mode 100644 index 0000000..d1bbdf0 --- /dev/null +++ b/src/dbus/meson.build @@ -0,0 +1,29 @@ +gnome = import('gnome') + + +gio_dep = dependency('gio-2.0', required: true) +aud_dbus_deps = [gio_dep] + + +if host_machine.system() != 'windows' + gio_unix_dep = dependency('gio-unix-2.0', required: true) + aud_dbus_deps += [gio_unix_dep] +endif + + +aud_dbus_src = gnome.gdbus_codegen('aud-dbus', + sources: 'aud-dbus.xml', + interface_prefix: 'org.atheme.', + namespace: 'Obj' +) +aud_dbus_deps += declare_dependency(sources: aud_dbus_src) + + +aud_dbus_lib = static_library('aud-dbus', + aud_dbus_src, + dependencies: aud_dbus_deps, + pic: true +) + + +aud_dbus_inc = include_directories('.') diff --git a/src/libaudcore/Makefile b/src/libaudcore/Makefile new file mode 100644 index 0000000..4b1c383 --- /dev/null +++ b/src/libaudcore/Makefile @@ -0,0 +1,113 @@ +SHARED_LIB = ${LIB_PREFIX}audcore${LIB_SUFFIX} +LIB_MAJOR = 5 +LIB_MINOR = 2 + +SRCS = adder.cc \ + art.cc \ + art-search.cc \ + audio.cc \ + audstrings.cc \ + charset.cc \ + config.cc \ + cue-cache.cc \ + drct.cc \ + effect.cc \ + equalizer.cc \ + equalizer-preset.cc \ + eventqueue.cc \ + fft.cc \ + history.cc \ + hook.cc \ + index.cc \ + inifile.cc \ + interface.cc \ + list.cc \ + logger.cc \ + mainloop.cc \ + multihash.cc \ + output.cc \ + parse.cc \ + playback.cc \ + playlist.cc \ + playlist-cache.cc \ + playlist-data.cc \ + playlist-files.cc \ + playlist-utils.cc \ + plugin-init.cc \ + plugin-load.cc \ + plugin-registry.cc \ + preferences.cc \ + probe.cc \ + probe-buffer.cc \ + ringbuf.cc \ + runtime.cc \ + scanner.cc \ + stringbuf.cc \ + strpool.cc \ + tinylock.cc \ + timer.cc \ + tuple.cc \ + tuple-compiler.cc \ + util.cc \ + vfs.cc \ + vfs_async.cc \ + vfs_local.cc \ + vis-runner.cc \ + visualization.cc + +INCLUDES = audio.h \ + audstrings.h \ + drct.h \ + equalizer.h \ + export.h \ + hook.h \ + i18n.h \ + index.h \ + inifile.h \ + interface.h \ + list.h \ + mainloop.h \ + multihash.h \ + objects.h \ + playlist.h \ + plugin.h \ + plugins.h \ + preferences.h \ + probe.h \ + ringbuf.h \ + runtime.h \ + templates.h \ + tinylock.h \ + threads.h \ + tuple.h \ + visualizer.h \ + vfs.h \ + vfs_async.h + +include ../../buildsys.mk +include ../../extra.mk + +includesubdir = libaudcore + +LD = ${CXX} + +CPPFLAGS := -I.. -I../.. \ + ${CPPFLAGS} \ + ${GLIB_CFLAGS} \ + ${GMODULE_CFLAGS} \ + ${QTCORE_CFLAGS} \ + -DINSTALL_BINDIR=\"${bindir}\" \ + -DINSTALL_DATADIR=\"${datadir}/audacious\" \ + -DINSTALL_PLUGINDIR=\"${plugindir}\" \ + -DINSTALL_LOCALEDIR=\"${localedir}\" \ + -DINSTALL_DESKTOPFILE=\"${datarootdir}/applications/audacious.desktop\" \ + -DINSTALL_ICONFILE=\"${datarootdir}/icons/hicolor/48x48/apps/audacious.png\" \ + -DLIBAUDCORE_BUILD + +CFLAGS += ${LIB_CFLAGS} + +LIBS := ../libguess/libguess.a \ + ${LIBS} -lm \ + ${GLIB_LIBS} \ + ${GMODULE_LIBS} \ + ${QTCORE_LIBS} diff --git a/src/libaudcore/adder.cc b/src/libaudcore/adder.cc new file mode 100644 index 0000000..8ee3bb9 --- /dev/null +++ b/src/libaudcore/adder.cc @@ -0,0 +1,620 @@ +/* + * adder.c + * Copyright 2011-2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "internal.h" +#include "playlist-internal.h" + +#include <stdio.h> +#include <string.h> + +#include "audstrings.h" +#include "hook.h" +#include "i18n.h" +#include "interface.h" +#include "list.h" +#include "mainloop.h" +#include "plugins-internal.h" +#include "probe.h" +#include "runtime.h" +#include "threads.h" +#include "tuple.h" +#include "vfs.h" + +// regrettably, strcmp_nocase can't be used directly as a +// callback for Index::sort due to taking a third argument; +// strcmp also triggers -Wnoexcept-type with GCC 7 +static int filename_compare(const char * a, const char * b) +#ifdef _WIN32 +{ + return strcmp_nocase(a, b); +} +#else +{ + return strcmp(a, b); +} +#endif + +struct AddTask : public ListNode +{ + Playlist playlist; + int at; + bool play; + Index<PlaylistAddItem> items; + Playlist::FilterFunc filter; + void * user; +}; + +struct AddResult : public ListNode +{ + Playlist playlist; + int at; + bool play; + String title; + Index<PlaylistAddItem> items; + bool saw_folder, filtered; +}; + +static void add_worker(); + +static List<AddTask> add_tasks; +static List<AddResult> add_results; +static Playlist current_playlist; + +static aud::mutex mutex; +static std::thread add_thread; +static bool add_thread_exited = false; +static QueuedFunc queued_add; +static QueuedFunc status_timer; + +static char status_path[512]; +static int status_count; +static bool status_shown = false; + +static void status_cb(void * unused) +{ + auto mh = mutex.take(); + + char scratch[128]; + snprintf( + scratch, sizeof scratch, + dngettext(PACKAGE, "%d file found", "%d files found", status_count), + status_count); + + if (aud_get_headless_mode()) + { + printf("Searching, %s ...\r", scratch); + fflush(stdout); + } + else + { + hook_call("ui show progress", status_path); + hook_call("ui show progress 2", scratch); + } + + status_shown = true; +} + +static void status_update(const char * filename, int found) +{ + auto mh = mutex.take(); + + snprintf(status_path, sizeof status_path, "%s", filename); + status_count = found; + + if (!status_timer.running()) + status_timer.start(250, status_cb, nullptr); +} + +static void status_done_locked() +{ + status_timer.stop(); + + if (status_shown) + { + if (aud_get_headless_mode()) + printf("\n"); + else + hook_call("ui hide progress", nullptr); + + status_shown = false; + } +} + +static void add_file(PlaylistAddItem && item, Playlist::FilterFunc filter, + void * user, AddResult * result, bool skip_invalid) +{ + AUDINFO("Adding file: %s\n", (const char *)item.filename); + status_update(item.filename, result->items.len()); + + /* + * If possible, we'll wait until the file is added to the playlist to probe + * it. There are a couple of reasons why we might need to probe it now: + * + * 1. We're adding a folder, and need to skip over non-audio files (the + * "skip invalid" flag indicates this case). + * 2. The file might have subtunes, which we need to expand in order to add + * them to the playlist correctly. + * + * If we already have metadata, or the file is itself a subtune, then + * neither of these reasons apply. + */ + if (!item.tuple.valid() && !is_subtune(item.filename)) + { + /* If we open the file to identify the decoder, we can re-use the same + * handle to read metadata. */ + VFSFile file; + + if (!item.decoder) + { + if (aud_get_bool("slow_probe")) + { + /* The slow path. User settings dictate that we should try to + * find a decoder even if we don't recognize the file extension. + */ + item.decoder = + aud_file_find_decoder(item.filename, false, file); + if (skip_invalid && !item.decoder) + return; + } + else + { + /* The fast path. First see whether any plugins recognize the + * file extension. Note that it's possible for multiple plugins + * to recognize the same extension (.ogg, for example). */ + int flags = probe_by_filename(item.filename); + if (skip_invalid && !(flags & PROBE_FLAG_HAS_DECODER)) + return; + + if ((flags & PROBE_FLAG_MIGHT_HAVE_SUBTUNES)) + { + /* At least one plugin recognized the file extension and + * indicated that there might be subtunes. Figure out for + * sure which decoder we need to use for this file. */ + item.decoder = + aud_file_find_decoder(item.filename, true, file); + if (skip_invalid && !item.decoder) + return; + } + } + } + + /* At this point we've either identified the decoder or determined that + * the file doesn't have any subtunes. If the former, read the tag so + * so we can expand any subtunes we find. */ + if (item.decoder && input_plugin_has_subtunes(item.decoder)) + aud_file_read_tag(item.filename, item.decoder, file, item.tuple); + } + + int n_subtunes = item.tuple.get_n_subtunes(); + + if (n_subtunes) + { + for (int sub = 0; sub < n_subtunes; sub++) + { + StringBuf subname = str_printf("%s?%d", (const char *)item.filename, + item.tuple.get_nth_subtune(sub)); + + if (!filter || filter(subname, user)) + add_file({String(subname), Tuple(), item.decoder}, filter, user, + result, false); + else + result->filtered = true; + } + } + else + result->items.append(std::move(item)); +} + +/* To prevent infinite recursion, we currently allow adding a folder from within + * a playlist, but not a playlist from within a folder, nor a second playlist + * from within a playlist (this last rule is enforced by setting + * <from_playlist> to true from within add_playlist()). */ +static void add_generic(PlaylistAddItem && item, Playlist::FilterFunc filter, + void * user, AddResult * result, bool save_title, + bool from_playlist); + +static void add_playlist(const char * filename, Playlist::FilterFunc filter, + void * user, AddResult * result, bool save_title) +{ + AUDINFO("Adding playlist: %s\n", filename); + status_update(filename, result->items.len()); + + String title; + Index<PlaylistAddItem> items; + + if (!playlist_load(filename, title, items)) + return; + + if (save_title) + result->title = title; + + for (auto & item : items) + add_generic(std::move(item), filter, user, result, false, true); +} + +static void add_cuesheets(Index<String> & files, Playlist::FilterFunc filter, + void * user, AddResult * result) +{ + Index<String> cuesheets; + + for (int i = 0; i < files.len();) + { + if (str_has_suffix_nocase(files[i], ".cue")) + cuesheets.move_from(files, i, -1, 1, true, true); + else + i++; + } + + if (!cuesheets.len()) + return; + + // sort cuesheet list in natural order + cuesheets.sort(str_compare_encoded); + + // sort file list in system-dependent order for duplicate removal + files.sort(filename_compare); + + for (String & cuesheet : cuesheets) + { + AUDINFO("Adding cuesheet: %s\n", (const char *)cuesheet); + status_update(cuesheet, result->items.len()); + + String title; // ignored + Index<PlaylistAddItem> items; + + if (!playlist_load(cuesheet, title, items)) + continue; + + String prev_filename; + for (auto & item : items) + { + String filename = item.tuple.get_str(Tuple::AudioFile); + if (!filename) + continue; // shouldn't happen + + if (!filter || filter(item.filename, user)) + add_file(std::move(item), filter, user, result, false); + else + result->filtered = true; + + // remove duplicates from file list + if (prev_filename && !filename_compare(filename, prev_filename)) + continue; + + int idx = files.bsearch((const char *)filename, filename_compare); + if (idx >= 0) + files.remove(idx, 1); + + prev_filename = std::move(filename); + } + } +} + +static void add_folder(const char * filename, Playlist::FilterFunc filter, + void * user, AddResult * result, bool save_title) +{ + AUDINFO("Adding folder: %s\n", filename); + status_update(filename, result->items.len()); + + String error; + Index<String> files = VFSFile::read_folder(filename, error); + Index<String> folders; + + if (error) + aud_ui_show_error(str_printf(_("Error reading %s:\n%s"), filename, + (const char *)error)); + + if (!files.len()) + return; + + if (save_title) + { + const char * slash = strrchr(filename, '/'); + if (slash) + result->title = String(str_decode_percent(slash + 1)); + } + + add_cuesheets(files, filter, user, result); + + // sort file list in natural order (must come after add_cuesheets) + files.sort(str_compare_encoded); + + for (const String & file : files) + { + if (filter && !filter(file, user)) + { + result->filtered = true; + continue; + } + + String error; + VFSFileTest mode = VFSFile::test_file( + file, VFSFileTest(VFS_IS_REGULAR | VFS_IS_SYMLINK | VFS_IS_DIR), + error); + + if (error) + AUDERR("%s: %s\n", (const char *)file, (const char *)error); + + if (mode & VFS_IS_SYMLINK) + continue; + + if (mode & VFS_IS_REGULAR) + add_file({file}, filter, user, result, true); + else if ((mode & VFS_IS_DIR) && aud_get_bool("recurse_folders")) + folders.append(file); + } + + // add folders after files + for (const String & folder : folders) + add_folder(folder, filter, user, result, false); +} + +static void add_generic(PlaylistAddItem && item, Playlist::FilterFunc filter, + void * user, AddResult * result, bool save_title, + bool from_playlist) +{ + if (!strstr(item.filename, "://")) + { + /* Let's not add random junk to the playlist. */ + AUDERR("Invalid URI: %s\n", (const char *)item.filename); + return; + } + + if (filter && !filter(item.filename, user)) + { + result->filtered = true; + return; + } + + /* If the item has a valid tuple or known decoder, or it's a subtune, then + * assume it's a playable file and skip some checks. */ + if (item.tuple.valid() || item.decoder || is_subtune(item.filename)) + add_file(std::move(item), filter, user, result, false); + else + { + int tests = 0; + if (!from_playlist) + tests |= VFS_NO_ACCESS; + if (!from_playlist || aud_get_bool("folders_in_playlist")) + tests |= VFS_IS_DIR; + + String error; + VFSFileTest mode = + VFSFile::test_file(item.filename, (VFSFileTest)tests, error); + + if ((mode & VFS_NO_ACCESS)) + aud_ui_show_error(str_printf(_("Error reading %s:\n%s"), + (const char *)item.filename, + (const char *)error)); + else if (mode & VFS_IS_DIR) + { + add_folder(item.filename, filter, user, result, save_title); + result->saw_folder = true; + } + else if ((!from_playlist) && + Playlist::filename_is_playlist(item.filename)) + add_playlist(item.filename, filter, user, result, save_title); + else + add_file(std::move(item), filter, user, result, false); + } +} + +static void start_thread_locked() +{ + if (add_thread_exited) + { + mutex.unlock(); + add_thread.join(); + mutex.lock(); + } + + if (!add_thread.joinable()) + { + add_thread = std::thread(add_worker); + add_thread_exited = false; + } +} + +static void stop_thread_locked() +{ + if (add_thread.joinable()) + { + mutex.unlock(); + add_thread.join(); + mutex.lock(); + add_thread_exited = false; + } +} + +static void add_finish(void * unused) +{ + auto mh = mutex.take(); + + for (SmartPtr<AddResult> result; result.capture(add_results.pop_head());) + { + if (!result->items.len()) + { + if (result->saw_folder && !result->filtered) + aud_ui_show_error(_("No files found.")); + continue; + } + + PlaylistEx playlist = result->playlist; + if (!playlist.exists()) /* playlist deleted */ + continue; + + if (result->play) + { + if (aud_get_bool("clear_playlist")) + playlist.remove_all_entries(); + else + playlist.queue_remove_all(); + } + + int count = playlist.n_entries(); + if (result->at < 0 || result->at > count) + result->at = count; + + if (result->title && !count) + { + if (!strcmp(playlist.get_title(), _("New Playlist"))) + playlist.set_title(result->title); + } + + /* temporarily disable scanning this playlist; the intent is to avoid + * scanning until the currently playing entry is known, at which time it + * can be scanned more efficiently (album art read in the same pass). */ + playlist_enable_scan(false); + playlist.insert_flat_items(result->at, std::move(result->items)); + + if (result->play) + { + if (!aud_get_bool("shuffle")) + playlist.set_position(result->at); + + playlist.start_playback(); + } + + playlist_enable_scan(true); + } + + if (add_thread_exited) + { + stop_thread_locked(); + status_done_locked(); + } + + mh.unlock(); // before calling hook + + hook_call("playlist add complete", nullptr); +} + +static void add_worker() +{ + auto mh = mutex.take(); + + for (SmartPtr<AddTask> task; task.capture(add_tasks.pop_head());) + { + current_playlist = task->playlist; + mh.unlock(); + + playlist_cache_load(task->items); + + AddResult * result = new AddResult(); + + result->playlist = task->playlist; + result->at = task->at; + result->play = task->play; + + bool save_title = (task->items.len() == 1); + + for (auto & item : task->items) + add_generic(std::move(item), task->filter, task->user, result, + save_title, false); + + mh.lock(); + current_playlist = Playlist(); + + if (!add_results.head()) + queued_add.queue(add_finish, nullptr); + + add_results.append(result); + } + + add_thread_exited = true; +} + +void adder_cleanup() +{ + auto mh = mutex.take(); + + add_tasks.clear(); + + stop_thread_locked(); + status_done_locked(); + + add_results.clear(); + + queued_add.stop(); +} + +EXPORT void Playlist::insert_entry(int at, const char * filename, + Tuple && tuple, bool play) const +{ + Index<PlaylistAddItem> items; + items.append(String(filename), std::move(tuple)); + + insert_items(at, std::move(items), play); +} + +EXPORT void Playlist::insert_items(int at, Index<PlaylistAddItem> && items, + bool play) const +{ + insert_filtered(at, std::move(items), nullptr, nullptr, play); +} + +EXPORT void Playlist::insert_filtered(int at, Index<PlaylistAddItem> && items, + Playlist::FilterFunc filter, void * user, + bool play) const +{ + auto mh = mutex.take(); + + AddTask * task = new AddTask(); + + task->playlist = *this; + task->at = at; + task->play = play; + task->items = std::move(items); + task->filter = filter; + task->user = user; + + add_tasks.append(task); + start_thread_locked(); +} + +EXPORT bool Playlist::add_in_progress() const +{ + auto mh = mutex.take(); + + for (AddTask * task = add_tasks.head(); task; task = add_tasks.next(task)) + { + if (task->playlist == *this) + return true; + } + + if (current_playlist == *this) + return true; + + for (AddResult * result = add_results.head(); result; + result = add_results.next(result)) + { + if (result->playlist == *this) + return true; + } + + return false; +} + +EXPORT bool Playlist::add_in_progress_any() +{ + auto mh = mutex.take(); + + return (add_tasks.head() || current_playlist != Playlist() || + add_results.head()); +} diff --git a/src/libaudcore/art-search.cc b/src/libaudcore/art-search.cc new file mode 100644 index 0000000..05f9723 --- /dev/null +++ b/src/libaudcore/art-search.cc @@ -0,0 +1,153 @@ +/* + * art-search.c + * Copyright 2006-2013 Michael Hanselmann, Yoshiki Yazawa, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "internal.h" + +#include <string.h> + +#include <glib.h> /* for g_dir_open, g_file_test */ + +#include "audstrings.h" +#include "index.h" +#include "runtime.h" + +struct SearchParams +{ + String filename; + Index<String> include, exclude; +}; + +static bool has_front_cover_extension(const char * name) +{ + const char * ext = strrchr(name, '.'); + if (!ext) + return false; + + return !strcmp_nocase(ext, ".jpg") || !strcmp_nocase(ext, ".jpeg") || + !strcmp_nocase(ext, ".png"); +} + +static bool cover_name_filter(const char * name, const Index<String> & keywords, + bool ret_on_empty) +{ + if (!keywords.len()) + return ret_on_empty; + + for (const String & keyword : keywords) + { + if (strstr_nocase(name, keyword)) + return true; + } + + return false; +} + +static String fileinfo_recursive_get_image(const char * path, + const SearchParams * params, + int depth) +{ + GDir * d = g_dir_open(path, 0, nullptr); + if (!d) + return String(); + + const char * name; + + if (aud_get_bool("use_file_cover") && !depth) + { + /* Look for images matching file name */ + while ((name = g_dir_read_name(d))) + { + StringBuf newpath = filename_build({path, name}); + + if (has_front_cover_extension(name) && + same_basename(name, params->filename) && + !g_file_test(newpath, G_FILE_TEST_IS_DIR)) + { + g_dir_close(d); + return String(newpath); + } + } + + g_dir_rewind(d); + } + + /* Search for files using filter */ + while ((name = g_dir_read_name(d))) + { + StringBuf newpath = filename_build({path, name}); + + if (has_front_cover_extension(name) && + cover_name_filter(name, params->include, true) && + !cover_name_filter(name, params->exclude, false) && + !g_file_test(newpath, G_FILE_TEST_IS_DIR)) + { + g_dir_close(d); + return String(newpath); + } + } + + g_dir_rewind(d); + + if (aud_get_bool("recurse_for_cover") && + depth < aud_get_int("recurse_for_cover_depth")) + { + /* Descend into directories recursively. */ + while ((name = g_dir_read_name(d))) + { + StringBuf newpath = filename_build({path, name}); + + if (g_file_test(newpath, G_FILE_TEST_IS_DIR)) + { + String tmp = + fileinfo_recursive_get_image(newpath, params, depth + 1); + + if (tmp) + { + g_dir_close(d); + return tmp; + } + } + } + } + + g_dir_close(d); + return String(); +} + +String art_search(const char * filename) +{ + StringBuf local = uri_to_filename(filename); + if (!local) + return String(); + + const char * elem = last_path_element(local); + if (!elem) + return String(); + + String include = aud_get_str("cover_name_include"); + String exclude = aud_get_str("cover_name_exclude"); + + SearchParams params = {String(elem), str_list_to_index(include, ", "), + str_list_to_index(exclude, ", ")}; + + cut_path_element(local, elem - local); + + String image_local = fileinfo_recursive_get_image(local, ¶ms, 0); + return image_local ? String(filename_to_uri(image_local)) : String(); +} diff --git a/src/libaudcore/art.cc b/src/libaudcore/art.cc new file mode 100644 index 0000000..a0ea230 --- /dev/null +++ b/src/libaudcore/art.cc @@ -0,0 +1,275 @@ +/* + * art.c + * Copyright 2011-2012 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "internal.h" +#include "probe.h" + +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <glib/gstdio.h> + +#include "audstrings.h" +#include "hook.h" +#include "mainloop.h" +#include "multihash.h" +#include "runtime.h" +#include "scanner.h" +#include "threads.h" +#include "vfs.h" + +#define FLAG_DONE 1 +#define FLAG_SENT 2 + +struct AudArtItem +{ + String filename; + int refcount; + int flag; + + /* album art as JPEG or PNG data */ + Index<char> data; + + /* album art as (possibly a temporary) file */ + String art_file; + bool is_temp; +}; + +static aud::mutex mutex; +static SimpleHash<String, AudArtItem> art_items; +static AudArtItem * current_item; +static QueuedFunc queued_requests; + +static Index<AudArtItem *> get_queued() +{ + auto mh = mutex.take(); + Index<AudArtItem *> queued; + + art_items.iterate([&](const String &, AudArtItem & item) { + if (item.flag == FLAG_DONE) + { + queued.append(&item); + item.flag = FLAG_SENT; + } + }); + + queued_requests.stop(); + + return queued; +} + +static void send_requests(void *) +{ + auto queued = get_queued(); + for (AudArtItem * item : queued) + { + hook_call("art ready", (void *)(const char *)item->filename); + aud_art_unref(item); /* release temporary reference */ + } +} + +static void finish_item(aud::mutex::holder &, AudArtItem * item, + Index<char> && data, String && art_file) +{ + /* already finished? */ + if (item->flag) + return; + + item->data = std::move(data); + item->art_file = std::move(art_file); + item->flag = FLAG_DONE; + + queued_requests.queue(send_requests, nullptr); +} + +static void request_callback(ScanRequest * request) +{ + auto mh = mutex.take(); + AudArtItem * item = art_items.lookup(request->filename); + + if (item) + finish_item(mh, item, std::move(request->image_data), + std::move(request->image_file)); +} + +static AudArtItem * art_item_get(aud::mutex::holder &, const String & filename, + bool * queued) +{ + if (queued) + *queued = false; + + // blacklist stdin + if (!strncmp(filename, "stdin://", 8)) + return nullptr; + + AudArtItem * item = art_items.lookup(filename); + + if (item && item->flag) + { + item->refcount++; + return item; + } + + if (!item) + { + item = art_items.add(filename, AudArtItem()); + item->filename = filename; + item->refcount = 1; /* temporary reference */ + + scanner_request( + new ScanRequest(filename, SCAN_IMAGE, request_callback)); + } + + if (queued) + *queued = true; + + return nullptr; +} + +static void art_item_unref(aud::mutex::holder &, AudArtItem * item) +{ + if (!--item->refcount) + { + /* delete temporary file */ + if (item->art_file && item->is_temp) + { + StringBuf local = uri_to_filename(item->art_file); + if (local) + g_unlink(local); + } + + art_items.remove(item->filename); + } +} + +static void clear_current(aud::mutex::holder & mh) +{ + if (current_item) + { + art_item_unref(mh, current_item); + current_item = nullptr; + } +} + +void art_cache_current(const String & filename, Index<char> && data, + String && art_file) +{ + auto mh = mutex.take(); + clear_current(mh); + + AudArtItem * item = art_items.lookup(filename); + + if (!item) + { + item = art_items.add(filename, AudArtItem()); + item->filename = filename; + item->refcount = 1; /* temporary reference */ + } + + finish_item(mh, item, std::move(data), std::move(art_file)); + + item->refcount++; + current_item = item; +} + +void art_clear_current() +{ + auto mh = mutex.take(); + clear_current(mh); +} + +void art_cleanup() +{ + auto queued = get_queued(); + for (AudArtItem * item : queued) + aud_art_unref(item); /* release temporary reference */ + + /* playback should already be stopped */ + assert(!current_item); + + if (art_items.n_items()) + AUDWARN("Album art reference count not zero at exit!\n"); +} + +EXPORT AudArtPtr aud_art_request(const char * file, int format, bool * queued) +{ + auto mh = mutex.take(); + AudArtItem * item = art_item_get(mh, String(file), queued); + + if (!item) + return AudArtPtr(); + + if (format & AUD_ART_DATA) + { + /* load data from external image file */ + if (!item->data.len() && item->art_file) + { + VFSFile file(item->art_file, "r"); + if (file) + item->data = file.read_all(); + } + + if (!item->data.len()) + { + art_item_unref(mh, item); + return AudArtPtr(); + } + } + + if (format & AUD_ART_FILE) + { + /* save data to temporary file */ + if (item->data.len() && !item->art_file) + { + String local = + write_temp_file(item->data.begin(), item->data.len()); + if (local) + { + item->art_file = String(filename_to_uri(local)); + item->is_temp = true; + } + } + + if (!item->art_file) + { + art_item_unref(mh, item); + return AudArtPtr(); + } + } + + return AudArtPtr(item); +} + +EXPORT const Index<char> * aud_art_data(const AudArtItem * item) +{ + return &item->data; +} +EXPORT const char * aud_art_file(const AudArtItem * item) +{ + return item->art_file; +} + +EXPORT void aud_art_unref(AudArtItem * item) +{ + auto mh = mutex.take(); + art_item_unref(mh, item); +} diff --git a/src/libaudcore/audio.cc b/src/libaudcore/audio.cc new file mode 100644 index 0000000..524ae7f --- /dev/null +++ b/src/libaudcore/audio.cc @@ -0,0 +1,506 @@ +/* + * audio.c + * Copyright 2009-2013 John Lindgren, Michał Lipski, and Anders Johansson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <fenv.h> +#include <math.h> +#include <stdint.h> + +#define WANT_AUD_BSWAP +#include "audio.h" +#include "objects.h" + +#define SW_VOLUME_RANGE 40 /* decibels */ + +struct packed24_t +{ + uint8_t b[3]; +}; +static_assert(sizeof(packed24_t) == 3, "invalid packed 24-bit type"); + +template<class Word> +void interlace_loop(const void * const * in, int channels, void * out, + int frames) +{ + for (int c = 0; c < channels; c++) + { + auto get = (const Word *)in[c]; + auto end = get + frames; + auto set = (Word *)out + c; + while (get < end) + { + *set = *get++; + set += channels; + } + } +} + +template<class Word> +void deinterlace_loop(const void * in, int channels, void * const * out, + int frames) +{ + for (int c = 0; c < channels; c++) + { + auto get = (const Word *)in + c; + auto set = (Word *)out[c]; + auto end = set + frames; + while (set < end) + { + *set++ = *get; + get += channels; + } + } +} + +EXPORT void audio_interlace(const void * const * in, int format, int channels, + void * out, int frames) +{ + switch (format) + { + case FMT_FLOAT: + interlace_loop<float>(in, channels, out, frames); + break; + + case FMT_S8: + case FMT_U8: + interlace_loop<int8_t>(in, channels, out, frames); + break; + + case FMT_S16_LE: + case FMT_S16_BE: + case FMT_U16_LE: + case FMT_U16_BE: + interlace_loop<int16_t>(in, channels, out, frames); + break; + + case FMT_S24_LE: + case FMT_S24_BE: + case FMT_U24_LE: + case FMT_U24_BE: + case FMT_S32_LE: + case FMT_S32_BE: + case FMT_U32_LE: + case FMT_U32_BE: + interlace_loop<int32_t>(in, channels, out, frames); + break; + + case FMT_S24_3LE: + case FMT_S24_3BE: + case FMT_U24_3LE: + case FMT_U24_3BE: + interlace_loop<packed24_t>(in, channels, out, frames); + break; + } +} + +EXPORT void audio_deinterlace(const void * in, int format, int channels, + void * const * out, int frames) +{ + switch (format) + { + case FMT_FLOAT: + deinterlace_loop<float>(in, channels, out, frames); + break; + + case FMT_S8: + case FMT_U8: + deinterlace_loop<int8_t>(in, channels, out, frames); + break; + + case FMT_S16_LE: + case FMT_S16_BE: + case FMT_U16_LE: + case FMT_U16_BE: + deinterlace_loop<int16_t>(in, channels, out, frames); + break; + + case FMT_S24_LE: + case FMT_S24_BE: + case FMT_U24_LE: + case FMT_U24_BE: + case FMT_S32_LE: + case FMT_S32_BE: + case FMT_U32_LE: + case FMT_U32_BE: + deinterlace_loop<int32_t>(in, channels, out, frames); + break; + + case FMT_S24_3LE: + case FMT_S24_3BE: + case FMT_U24_3LE: + case FMT_U24_3BE: + deinterlace_loop<packed24_t>(in, channels, out, frames); + break; + } +} + +static constexpr bool is_le(int format) +{ + return format == FMT_S16_LE || format == FMT_U16_LE || + format == FMT_S24_LE || format == FMT_U24_LE || + format == FMT_S32_LE || format == FMT_U32_LE || + format == FMT_S24_3LE || format == FMT_U24_3LE; +} + +static constexpr bool is_signed(int format) +{ + return (format == FMT_S8 || format == FMT_S16_LE || format == FMT_S16_BE || + format == FMT_S24_LE || format == FMT_S24_BE || + format == FMT_S32_LE || format == FMT_S32_BE || + format == FMT_S24_3LE || format == FMT_S24_3BE); +} + +static constexpr unsigned neg_range(int format) +{ + return (format >= FMT_S32_LE && format < FMT_S24_3LE) + ? 0x80000000 + : (format >= FMT_S24_LE) + ? 0x800000 + : (format >= FMT_S16_LE) ? 0x8000 : 0x80; +} + +// 0x7fffff80 = largest representable floating-point value before 2^31 +static constexpr unsigned pos_range(int format) +{ + return (format >= FMT_S32_LE && format < FMT_S24_3LE) + ? 0x7fffff80 + : (format >= FMT_S24_LE) + ? 0x7fffff + : (format >= FMT_S16_LE) ? 0x7fff : 0x7f; +} + +template<class T> +T do_swap(T value) +{ + return value; +} +template<> +int16_t do_swap(int16_t value) +{ + return bswap16(value); +} +template<> +int32_t do_swap(int32_t value) +{ + return bswap32(value); +} + +template<int format, class Word, class Int> +struct Convert +{ +#ifdef WORDS_BIGENDIAN + static constexpr bool native_le = false; +#else + static constexpr bool native_le = true; +#endif + + static Int to_int(Word value) + { + if (is_le(format) ^ native_le) + value = do_swap(value); + if (is_signed(format)) + value += neg_range(format); + if (format >= FMT_S24_LE && format <= FMT_U24_BE) + value &= 0xffffff; /* ignore high byte */ + + return value - neg_range(format); + } + + static Word to_word(Int value) + { + if (!is_signed(format)) + value += neg_range(format); + if (format >= FMT_S24_LE && format <= FMT_U24_BE) + value &= 0xffffff; /* zero high byte */ + if (is_le(format) ^ native_le) + value = do_swap(value); + + return value; + } +}; + +template<int format> +struct Convert<format, packed24_t, int32_t> +{ + static int32_t to_int(packed24_t value) + { + uint8_t hi, mid, lo; + + if (is_le(format)) + hi = value.b[2], mid = value.b[1], lo = value.b[0]; + else + hi = value.b[0], mid = value.b[1], lo = value.b[2]; + + if (!is_signed(format)) + hi -= 0x80; + + return (int8_t(hi) << 16) | (mid << 8) | lo; + } + + static packed24_t to_word(int32_t value) + { + auto hi = uint8_t(value >> 16), mid = uint8_t(value >> 8), + lo = uint8_t(value); + + if (!is_signed(format)) + hi += 0x80; + + if (is_le(format)) + return {{lo, mid, hi}}; + else + return {{hi, mid, lo}}; + } +}; + +template<int format, class Word, class Int = Word> +void from_int_loop(const void * in_, float * out, int samples) +{ + auto in = (const Word *)in_; + auto end = in + samples; + while (in < end) + { + Int value = Convert<format, Word, Int>::to_int(*in++); + *out++ = value * (1.0f / neg_range(format)); + } +} + +template<int format, class Word, class Int = Word> +void to_int_loop(const float * in, void * out_, int samples) +{ + auto end = in + samples; + auto out = (Word *)out_; + while (in < end) + { + float f = (*in++) * neg_range(format); + f = aud::clamp(f, -(float)neg_range(format), (float)pos_range(format)); + *out++ = Convert<format, Word, Int>::to_word(lrintf(f)); + } +} + +EXPORT void audio_from_int(const void * in, int format, float * out, + int samples) +{ + switch (format) + { + case FMT_S8: + from_int_loop<FMT_S8, int8_t>(in, out, samples); + break; + case FMT_U8: + from_int_loop<FMT_U8, int8_t>(in, out, samples); + break; + + case FMT_S16_LE: + from_int_loop<FMT_S16_LE, int16_t>(in, out, samples); + break; + case FMT_S16_BE: + from_int_loop<FMT_S16_BE, int16_t>(in, out, samples); + break; + case FMT_U16_LE: + from_int_loop<FMT_U16_LE, int16_t>(in, out, samples); + break; + case FMT_U16_BE: + from_int_loop<FMT_U16_BE, int16_t>(in, out, samples); + break; + + case FMT_S24_LE: + from_int_loop<FMT_S24_LE, int32_t>(in, out, samples); + break; + case FMT_S24_BE: + from_int_loop<FMT_S24_BE, int32_t>(in, out, samples); + break; + case FMT_U24_LE: + from_int_loop<FMT_U24_LE, int32_t>(in, out, samples); + break; + case FMT_U24_BE: + from_int_loop<FMT_U24_BE, int32_t>(in, out, samples); + break; + + case FMT_S32_LE: + from_int_loop<FMT_S32_LE, int32_t>(in, out, samples); + break; + case FMT_S32_BE: + from_int_loop<FMT_S32_BE, int32_t>(in, out, samples); + break; + case FMT_U32_LE: + from_int_loop<FMT_U32_LE, int32_t>(in, out, samples); + break; + case FMT_U32_BE: + from_int_loop<FMT_U32_BE, int32_t>(in, out, samples); + break; + + case FMT_S24_3LE: + from_int_loop<FMT_S24_3LE, packed24_t, int32_t>(in, out, samples); + break; + case FMT_S24_3BE: + from_int_loop<FMT_S24_3BE, packed24_t, int32_t>(in, out, samples); + break; + case FMT_U24_3LE: + from_int_loop<FMT_U24_3LE, packed24_t, int32_t>(in, out, samples); + break; + case FMT_U24_3BE: + from_int_loop<FMT_U24_3BE, packed24_t, int32_t>(in, out, samples); + break; + } +} + +EXPORT void audio_to_int(const float * in, void * out, int format, int samples) +{ + int save = fegetround(); + fesetround(FE_TONEAREST); + + switch (format) + { + case FMT_S8: + to_int_loop<FMT_S8, int8_t>(in, out, samples); + break; + case FMT_U8: + to_int_loop<FMT_U8, int8_t>(in, out, samples); + break; + + case FMT_S16_LE: + to_int_loop<FMT_S16_LE, int16_t>(in, out, samples); + break; + case FMT_S16_BE: + to_int_loop<FMT_S16_BE, int16_t>(in, out, samples); + break; + case FMT_U16_LE: + to_int_loop<FMT_U16_LE, int16_t>(in, out, samples); + break; + case FMT_U16_BE: + to_int_loop<FMT_U16_BE, int16_t>(in, out, samples); + break; + + case FMT_S24_LE: + to_int_loop<FMT_S24_LE, int32_t>(in, out, samples); + break; + case FMT_S24_BE: + to_int_loop<FMT_S24_BE, int32_t>(in, out, samples); + break; + case FMT_U24_LE: + to_int_loop<FMT_U24_LE, int32_t>(in, out, samples); + break; + case FMT_U24_BE: + to_int_loop<FMT_U24_BE, int32_t>(in, out, samples); + break; + + case FMT_S32_LE: + to_int_loop<FMT_S32_LE, int32_t>(in, out, samples); + break; + case FMT_S32_BE: + to_int_loop<FMT_S32_BE, int32_t>(in, out, samples); + break; + case FMT_U32_LE: + to_int_loop<FMT_U32_LE, int32_t>(in, out, samples); + break; + case FMT_U32_BE: + to_int_loop<FMT_U32_BE, int32_t>(in, out, samples); + break; + + case FMT_S24_3LE: + to_int_loop<FMT_S24_3LE, packed24_t, int32_t>(in, out, samples); + break; + case FMT_S24_3BE: + to_int_loop<FMT_S24_3BE, packed24_t, int32_t>(in, out, samples); + break; + case FMT_U24_3LE: + to_int_loop<FMT_U24_3LE, packed24_t, int32_t>(in, out, samples); + break; + case FMT_U24_3BE: + to_int_loop<FMT_U24_3BE, packed24_t, int32_t>(in, out, samples); + break; + } + + fesetround(save); +} + +EXPORT void audio_amplify(float * data, int channels, int frames, + const float * factors) +{ + float * end = data + channels * frames; + int channel; + + while (data < end) + { + for (channel = 0; channel < channels; channel++) + { + *data = *data * factors[channel]; + data++; + } + } +} + +EXPORT void audio_amplify(float * data, int channels, int frames, + StereoVolume volume) +{ + if (channels < 1 || channels > AUD_MAX_CHANNELS) + return; + + if (volume.left == 100 && volume.right == 100) + return; + + float lfactor = 0, rfactor = 0; + float factors[AUD_MAX_CHANNELS]; + + if (volume.left > 0) + lfactor = + powf(10, (float)SW_VOLUME_RANGE * (volume.left - 100) / 100 / 20); + if (volume.right > 0) + rfactor = + powf(10, (float)SW_VOLUME_RANGE * (volume.right - 100) / 100 / 20); + + if (channels == 2) + { + factors[0] = lfactor; + factors[1] = rfactor; + } + else + { + for (int c = 0; c < channels; c++) + factors[c] = aud::max(lfactor, rfactor); + } + + audio_amplify(data, channels, frames, factors); +} + +/* linear approximation of y = sin(x) */ +/* contributed by Anders Johansson */ +EXPORT void audio_soft_clip(float * data, int samples) +{ + float * end = data + samples; + + while (data < end) + { + float x = *data; + float y = fabsf(x); + + if (y <= 0.4) + ; /* (0, 0.4) -> (0, 0.4) */ + else if (y <= 0.7) + y = 0.8 * y + 0.08; /* (0.4, 0.7) -> (0.4, 0.64) */ + else if (y <= 1.0) + y = 0.7 * y + 0.15; /* (0.7, 1) -> (0.64, 0.85) */ + else if (y <= 1.3) + y = 0.4 * y + 0.45; /* (1, 1.3) -> (0.85, 0.97) */ + else if (y <= 1.5) + y = 0.15 * y + 0.775; /* (1.3, 1.5) -> (0.97, 1) */ + else + y = 1.0; /* (1.5, inf) -> 1 */ + + *data++ = (x > 0) ? y : -y; + } +} diff --git a/src/libaudcore/audio.h.in b/src/libaudcore/audio.h.in new file mode 100644 index 0000000..c5b41be --- /dev/null +++ b/src/libaudcore/audio.h.in @@ -0,0 +1,139 @@ +/* + * audio.h + * Copyright 2009-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_AUDIO_H +#define LIBAUDCORE_AUDIO_H + +#define AUD_MAX_CHANNELS 10 + +enum { + FMT_FLOAT, + FMT_S8, FMT_U8, + FMT_S16_LE, FMT_S16_BE, FMT_U16_LE, FMT_U16_BE, + FMT_S24_LE, FMT_S24_BE, FMT_U24_LE, FMT_U24_BE, /* padded to 4 bytes */ + FMT_S32_LE, FMT_S32_BE, FMT_U32_LE, FMT_U32_BE, + FMT_S24_3LE, FMT_S24_3BE, FMT_U24_3LE, FMT_U24_3BE }; /* packed in 3 bytes */ + +struct ReplayGainInfo { + float track_gain; /* dB */ + float track_peak; /* 0-1 */ + float album_gain; /* dB */ + float album_peak; /* 0-1 */ +}; + +struct StereoVolume { + int left, right; +}; + +#ifdef WANT_AUD_BSWAP + +#include <stdint.h> + +#undef bswap16 +#undef bswap32 +#undef bswap64 + +/* GCC will optimize these to appropriate bswap instructions */ +constexpr uint16_t bswap16 (uint16_t x) + { return ((x & 0xff00) >> 8) | ((x & 0x00ff) << 8); } + +constexpr uint32_t bswap32 (uint32_t x) +{ + return ((x & 0xff000000) >> 24) | ((x & 0x00ff0000) >> 8) | + ((x & 0x0000ff00) << 8) | ((x & 0x000000ff) << 24); +} + +constexpr uint64_t bswap64 (uint64_t x) +{ + return ((x & 0xff00000000000000) >> 56) | ((x & 0x00ff000000000000) >> 40) | + ((x & 0x0000ff0000000000) >> 24) | ((x & 0x000000ff00000000) >> 8) | + ((x & 0x00000000ff000000) << 8) | ((x & 0x0000000000ff0000) << 24) | + ((x & 0x000000000000ff00) << 40) | ((x & 0x00000000000000ff) << 56); +} + +#endif // WANT_AUD_BSWAP + +#if @BIGENDIAN@ + +#define FMT_S16_NE FMT_S16_BE +#define FMT_U16_NE FMT_U16_BE +#define FMT_S24_NE FMT_S24_BE +#define FMT_U24_NE FMT_U24_BE +#define FMT_S32_NE FMT_S32_BE +#define FMT_U32_NE FMT_U32_BE +#define FMT_S24_3NE FMT_S24_3BE +#define FMT_U24_3NE FMT_U24_3BE + +#ifdef WANT_AUD_BSWAP +#define FROM_BE16(x) (x) +#define FROM_BE32(x) (x) +#define FROM_BE64(x) (x) +#define FROM_LE16(x) (bswap16 (x)) +#define FROM_LE32(x) (bswap32 (x)) +#define FROM_LE64(x) (bswap64 (x)) +#define TO_BE16(x) (x) +#define TO_BE32(x) (x) +#define TO_BE64(x) (x) +#define TO_LE16(x) (bswap16 (x)) +#define TO_LE32(x) (bswap32 (x)) +#define TO_LE64(x) (bswap64 (x)) +#endif + +#else // ! BIGENDIAN + +#define FMT_S16_NE FMT_S16_LE +#define FMT_U16_NE FMT_U16_LE +#define FMT_S24_NE FMT_S24_LE +#define FMT_U24_NE FMT_U24_LE +#define FMT_S32_NE FMT_S32_LE +#define FMT_U32_NE FMT_U32_LE +#define FMT_S24_3NE FMT_S24_3LE +#define FMT_U24_3NE FMT_U24_3LE + +#ifdef WANT_AUD_BSWAP +#define FROM_BE16(x) (bswap16 (x)) +#define FROM_BE32(x) (bswap32 (x)) +#define FROM_BE64(x) (bswap64 (x)) +#define FROM_LE16(x) (x) +#define FROM_LE32(x) (x) +#define FROM_LE64(x) (x) +#define TO_BE16(x) (bswap16 (x)) +#define TO_BE32(x) (bswap32 (x)) +#define TO_BE64(x) (bswap64 (x)) +#define TO_LE16(x) (x) +#define TO_LE32(x) (x) +#define TO_LE64(x) (x) +#endif + +#endif + +#define FMT_SIZEOF(f) (((f) >= FMT_S24_3LE) ? 3 : \ + ((f) >= FMT_S24_LE) ? 4 : \ + ((f) >= FMT_S16_LE) ? 2 : \ + ((f) >= FMT_S8) ? 1 : sizeof (float)) + +void audio_interlace (const void * const * in, int format, int channels, void * out, int frames); +void audio_deinterlace (const void * in, int format, int channels, void * const * out, int frames); +void audio_from_int (const void * in, int format, float * out, int samples); +void audio_to_int (const float * in, void * out, int format, int samples); +void audio_amplify (float * data, int channels, int frames, const float * factors); +void audio_amplify (float * data, int channels, int frames, StereoVolume volume); +void audio_soft_clip (float * data, int samples); + +#endif /* LIBAUDCORE_AUDIO_H */ diff --git a/src/libaudcore/audstrings.cc b/src/libaudcore/audstrings.cc new file mode 100644 index 0000000..d0f2264 --- /dev/null +++ b/src/libaudcore/audstrings.cc @@ -0,0 +1,1193 @@ +/* + * audstrings.c + * Copyright 2009-2012 John Lindgren and Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "audstrings.h" + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <new> + +#include <glib.h> + +#include "i18n.h" +#include "index.h" +#include "internal.h" +#include "runtime.h" + +#define MAX_POW10 9 +static const unsigned int_pow10[MAX_POW10 + 1] = { + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; + +static const char ascii_to_hex[256] = + "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0" + "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0" + "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0" + "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\x0\x0\x0\x0\x0\x0" + "\x0\xa\xb\xc\xd\xe\xf\x0\x0\x0\x0\x0\x0\x0\x0\x0" + "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0" + "\x0\xa\xb\xc\xd\xe\xf\x0\x0\x0\x0\x0\x0\x0\x0\x0" + "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"; + +static const char hex_to_ascii[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + +static const char uri_legal_table[256] = + "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0" + "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0" + "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x1\x1\x1" // '-' '.' '/' +#ifdef _WIN32 + /* We assume ':' is used with a "reserved purpose" (i.e. drive letter). + * This assumption might need to be reconsidered for non-file URIs. */ + "\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x0\x0\x0\x0\x0" // 0-9 ':' +#else + "\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x0\x0\x0\x0\x0\x0" // 0-9 +#endif + "\x0\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1" // A-O + "\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x0\x0\x0\x0\x1" // P-Z '_' + "\x0\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1" // a-o + "\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x0\x0\x0\x1\x0"; // p-z '~' + +static const char swap_case[256] = + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0abcdefghijklmnopqrstuvwxyz\0\0\0\0\0" + "\0ABCDEFGHIJKLMNOPQRSTUVWXYZ\0\0\0\0\0"; + +#define FROM_HEX(c) (ascii_to_hex[(unsigned char)(c)]) +#define TO_HEX(i) (hex_to_ascii[(i)&15]) +#define IS_LEGAL(c) (uri_legal_table[(unsigned char)(c)]) +#define SWAP_CASE(c) (swap_case[(unsigned char)(c)]) + +#ifdef _WIN32 +#define IS_SEP(c) ((c) == '/' || (c) == '\\') +#else +#define IS_SEP(c) ((c) == '/') +#endif + +/* strcmp() that handles nullptr safely */ +EXPORT int strcmp_safe(const char * a, const char * b, int len) +{ + if (!a) + return b ? -1 : 0; + if (!b) + return 1; + + return len < 0 ? strcmp(a, b) : strncmp(a, b, len); +} + +/* ASCII version of strcasecmp, also handles nullptr safely */ +EXPORT int strcmp_nocase(const char * a, const char * b, int len) +{ + if (!a) + return b ? -1 : 0; + if (!b) + return 1; + + return len < 0 ? g_ascii_strcasecmp(a, b) : g_ascii_strncasecmp(a, b, len); +} + +/* strlen() if <len> is negative, otherwise strnlen() */ +EXPORT int strlen_bounded(const char * s, int len) +{ + if (len < 0) + return strlen(s); + + const char * nul = (const char *)memchr(s, 0, len); + if (nul) + return nul - s; + + return len; +} + +EXPORT StringBuf str_copy(const char * s, int len) +{ + if (len < 0) + len = strlen(s); + + StringBuf str(len); + memcpy(str, s, len); + return str; +} + +EXPORT StringBuf str_concat(const std::initializer_list<const char *> & strings) +{ + StringBuf str(-1); + char * set = str; + int left = str.len(); + + for (const char * s : strings) + { + int len = strlen(s); + if (len > left) + throw std::bad_alloc(); + + memcpy(set, s, len); + + set += len; + left -= len; + } + + str.resize(set - str); + return str; +} + +EXPORT StringBuf str_printf(const char * format, ...) +{ + va_list args; + va_start(args, format); + StringBuf str = str_vprintf(format, args); + va_end(args); + return str; +} + +EXPORT void str_append_printf(StringBuf & str, const char * format, ...) +{ + va_list args; + va_start(args, format); + str_append_vprintf(str, format, args); + va_end(args); +} + +EXPORT StringBuf str_vprintf(const char * format, va_list args) +{ + StringBuf str(-1); + int len = vsnprintf(str, str.len(), format, args); + str.resize(len); + return str; +} + +EXPORT void str_append_vprintf(StringBuf & str, const char * format, + va_list args) +{ + int len0 = str.len(); + str.resize(-1); + int len1 = vsnprintf(str + len0, str.len() - len0, format, args); + str.resize(len0 + len1); +} + +EXPORT bool str_has_prefix_nocase(const char * str, const char * prefix) +{ + return !g_ascii_strncasecmp(str, prefix, strlen(prefix)); +} + +EXPORT bool str_has_suffix_nocase(const char * str, const char * suffix) +{ + int len1 = strlen(str); + int len2 = strlen(suffix); + + if (len2 > len1) + return false; + + return !g_ascii_strcasecmp(str + len1 - len2, suffix); +} + +/* Bernstein's hash function (unrolled version): + * h(0) = 5381 + * h(n) = 33 * h(n-1) + c + * + * This function is more than twice as fast as g_str_hash (a simpler version of + * Bernstein's hash) and even slightly faster than Murmur 3. */ + +EXPORT unsigned str_calc_hash(const char * s) +{ + unsigned h = 5381; + + int len = strlen(s); + + while (len >= 8) + { + h = h * 1954312449 + (unsigned)s[0] * 3963737313 + + (unsigned)s[1] * 1291467969 + (unsigned)s[2] * 39135393 + + (unsigned)s[3] * 1185921 + (unsigned)s[4] * 35937 + + (unsigned)s[5] * 1089 + (unsigned)s[6] * 33 + s[7]; + + s += 8; + len -= 8; + } + + if (len >= 4) + { + h = h * 1185921 + (unsigned)s[0] * 35937 + (unsigned)s[1] * 1089 + + (unsigned)s[2] * 33 + s[3]; + + s += 4; + len -= 4; + } + + switch (len) + { + case 3: + h = h * 33 + (*s++); + case 2: + h = h * 33 + (*s++); + case 1: + h = h * 33 + (*s++); + } + + return h; +} + +EXPORT const char * strstr_nocase(const char * haystack, const char * needle) +{ + while (1) + { + const char * ap = haystack; + const char * bp = needle; + + while (1) + { + char a = *ap++; + char b = *bp++; + + if (!b) /* all of needle matched */ + return (char *)haystack; + if (!a) /* end of haystack reached */ + return nullptr; + + if (a != b && a != SWAP_CASE(b)) + break; + } + + haystack++; + } +} + +EXPORT const char * strstr_nocase_utf8(const char * haystack, + const char * needle) +{ + while (1) + { + const char * ap = haystack; + const char * bp = needle; + + while (1) + { + gunichar a = g_utf8_get_char(ap); + gunichar b = g_utf8_get_char(bp); + + if (!b) /* all of needle matched */ + return (char *)haystack; + if (!a) /* end of haystack reached */ + return nullptr; + + if (a != b && + (a < 128 ? (gunichar)SWAP_CASE(a) != b + : g_unichar_tolower(a) != g_unichar_tolower(b))) + break; + + ap = g_utf8_next_char(ap); + bp = g_utf8_next_char(bp); + } + + haystack = g_utf8_next_char(haystack); + } +} + +EXPORT StringBuf str_tolower(const char * str) +{ + StringBuf buf(strlen(str)); + char * set = buf; + + while (*str) + *set++ = g_ascii_tolower(*str++); + + return buf; +} + +EXPORT StringBuf str_tolower_utf8(const char * str) +{ + StringBuf buf(6 * strlen(str)); + char * set = buf; + gunichar c; + + while ((c = g_utf8_get_char(str))) + { + if (c < 128) + *set++ = g_ascii_tolower(c); + else + set += g_unichar_to_utf8(g_unichar_tolower(c), set); + + str = g_utf8_next_char(str); + } + + buf.resize(set - buf); + return buf; +} + +EXPORT StringBuf str_toupper(const char * str) +{ + StringBuf buf(strlen(str)); + char * set = buf; + + while (*str) + *set++ = g_ascii_toupper(*str++); + + return buf; +} + +EXPORT StringBuf str_toupper_utf8(const char * str) +{ + StringBuf buf(6 * strlen(str)); + char * set = buf; + gunichar c; + + while ((c = g_utf8_get_char(str))) + { + if (c < 128) + *set++ = g_ascii_toupper(c); + else + set += g_unichar_to_utf8(g_unichar_toupper(c), set); + + str = g_utf8_next_char(str); + } + + buf.resize(set - buf); + return buf; +} + +EXPORT void str_replace_char(char * string, char old_c, char new_c) +{ + while ((string = strchr(string, old_c))) + *string++ = new_c; +} + +/* Percent-decodes <len> bytes of <str>. If <len> is negative, decodes all of + * <str>. */ + +EXPORT StringBuf str_decode_percent(const char * str, int len) +{ + if (len < 0) + len = strlen(str); + + StringBuf buf(len); + char * out = buf; + + while (1) + { + const char * p = (const char *)memchr(str, '%', len); + if (!p) + break; + + int block = p - str; + memcpy(out, str, block); + + str += block; + out += block; + len -= block; + + if (len < 3) + break; + + *out++ = (FROM_HEX(str[1]) << 4) | FROM_HEX(str[2]); + + str += 3; + len -= 3; + } + + memcpy(out, str, len); + buf.resize(out + len - buf); + return buf; +} + +/* Percent-encodes <len> bytes of <str>. If <len> is negative, encodes all of + * <str>. */ + +EXPORT StringBuf str_encode_percent(const char * str, int len) +{ + if (len < 0) + len = strlen(str); + + StringBuf buf(3 * len); + char * out = buf; + + while (len--) + { + char c = *str++; + + if (IS_LEGAL(c)) + *out++ = c; + else + { + *out++ = '%'; + *out++ = TO_HEX((unsigned char)c >> 4); + *out++ = TO_HEX(c & 0xF); + } + } + + buf.resize(out - buf); + return buf; +} + +EXPORT StringBuf filename_normalize(StringBuf && filename) +{ + int len; + char * s; + +#ifdef _WIN32 + /* convert slash to backslash on Windows */ + str_replace_char(filename, '/', '\\'); +#endif + + /* remove current directory (".") elements */ + while ((len = filename.len()) >= 2 && + (!strcmp((s = filename + len - 2), G_DIR_SEPARATOR_S ".") || + (s = strstr(filename, G_DIR_SEPARATOR_S "." G_DIR_SEPARATOR_S)))) + filename.remove(s + 1 - filename, + aud::min(s + 3, filename + len) - (s + 1)); + + /* remove parent directory ("..") elements */ + while ((len = filename.len()) >= 3 && + (!strcmp((s = filename + len - 3), G_DIR_SEPARATOR_S "..") || + (s = strstr(filename, G_DIR_SEPARATOR_S ".." G_DIR_SEPARATOR_S)))) + { + *s = 0; + char * s2 = strrchr(filename, G_DIR_SEPARATOR); + if (!s2) + *(s2 = s) = G_DIR_SEPARATOR; + + filename.remove(s2 + 1 - filename, + aud::min(s + 4, filename + len) - (s2 + 1)); + } + + /* remove trailing slash */ +#ifdef _WIN32 + if ((len = filename.len()) > 3 && + filename[len - 1] == '\\') /* leave "C:\" */ +#else + if ((len = filename.len()) > 1 && + filename[len - 1] == '/') /* leave leading "/" */ +#endif + filename.resize(len - 1); + + return std::move(filename); +} + +/* note #1: recommended order is filename_contract(filename_normalize(f)) */ +/* note #2: currently assumes filename is UTF-8 (intended for display) */ +EXPORT StringBuf filename_contract(StringBuf && filename) +{ + /* replace home folder with '~' */ + const char * home = get_home_utf8(); + int homelen = home ? strlen(home) : 0; + + if (homelen && !strncmp(filename, home, homelen) && + (!filename[homelen] || IS_SEP(filename[homelen]))) + { + filename[0] = '~'; + filename.remove(1, homelen - 1); + } + + return std::move(filename); +} + +/* note #1: recommended order is filename_normalize(filename_expand(f)) */ +/* note #2: currently assumes filename is UTF-8 (intended for display) */ +EXPORT StringBuf filename_expand(StringBuf && filename) +{ + /* expand leading '~' */ + if (filename[0] == '~' && (!filename[1] || IS_SEP(filename[1]))) + { + const char * home = get_home_utf8(); + + if (home && home[0]) + { + filename[0] = home[0]; + filename.insert(1, home + 1, -1); + } + } + + return std::move(filename); +} + +EXPORT StringBuf filename_get_parent(const char * filename) +{ + StringBuf buf = filename_normalize(str_copy(filename)); + const char * base = last_path_element(buf); + + if (!base) + return StringBuf(); + +#ifdef _WIN32 + if (base - buf > 3) /* leave "C:\" */ +#else + if (base - buf > 1) /* leave leading "/" */ +#endif + buf.resize(base - buf - 1); + else + buf.resize(base - buf); + + return buf; +} + +EXPORT StringBuf filename_get_base(const char * filename) +{ + StringBuf buf = filename_normalize(str_copy(filename)); + const char * base = last_path_element(buf); + + if (base) + buf.remove(0, base - buf); + + return buf; +} + +EXPORT StringBuf +filename_build(const std::initializer_list<const char *> & elems) +{ + StringBuf str(-1); + char * set = str; + int left = str.len(); + + for (const char * s : elems) + { + if (set > str && !IS_SEP(set[-1])) + { + if (!left) + throw std::bad_alloc(); + + *set++ = G_DIR_SEPARATOR; + left--; + } + + int len = strlen(s); + if (len > left) + throw std::bad_alloc(); + + memcpy(set, s, len); + + set += len; + left -= len; + } + + str.resize(set - str); + return str; +} + +#ifdef _WIN32 +#define URI_PREFIX "file:///" +#define URI_PREFIX_LEN 8 +#else +#define URI_PREFIX "file://" +#define URI_PREFIX_LEN 7 +#endif + +/* Like g_filename_to_uri, but converts the filename from the system locale to + * UTF-8 before percent-encoding (except on Windows, where filenames are assumed + * to be UTF-8). On Windows, replaces '\' with '/' and adds a leading '/'. */ + +EXPORT StringBuf filename_to_uri(const char * name) +{ +#ifdef _WIN32 + StringBuf buf = str_copy(name); + str_replace_char(buf, '\\', '/'); +#else + StringBuf buf; + + /* convert from locale if: + * 1) system locale is not UTF-8, and + * 2) filename is not already valid UTF-8 */ + if (!g_get_charset(nullptr) && !g_utf8_validate(name, -1, nullptr)) + buf = str_from_locale(name); +#endif + + buf = str_encode_percent(buf ? buf : name); + buf.insert(0, URI_PREFIX); + return buf.settle(); +} + +/* Like g_filename_from_uri, but optionally converts the filename from UTF-8 to + * the system locale after percent-decoding (except on Windows, where filenames + * are assumed to be UTF-8). On Windows, strips the leading '/' and replaces + * '/' with '\'. If the input is not a valid URI, it is assumed to be a local + * filename already and is not percent-decoded. */ + +EXPORT StringBuf uri_to_filename(const char * uri, bool use_locale) +{ + StringBuf buf; + + if (!strncmp(uri, URI_PREFIX, URI_PREFIX_LEN)) + buf = str_decode_percent(uri + URI_PREFIX_LEN); + else if (!strstr(uri, "://")) /* already a local filename? */ + buf = str_copy(uri); + else + return StringBuf(); + +#ifndef _WIN32 + /* convert to locale if: + * 1) use_locale flag was not set to false, and + * 2) system locale is not UTF-8, and + * 3) decoded URI is valid UTF-8 */ + if (use_locale && !g_get_charset(nullptr) && + g_utf8_validate(buf, buf.len(), nullptr)) + { + StringBuf locale = str_to_locale(buf); + if (locale) + buf = std::move(locale); + } +#endif + + /* if UTF-8 was requested, make sure the result is valid */ + if (!use_locale) + { + buf = str_to_utf8(std::move(buf)); + if (!buf) + return StringBuf(); + } + + return filename_normalize(buf.settle()); +} + +/* Formats a URI for human-readable display. Percent-decodes and, for file:// + * URI's, converts to filename format, but in UTF-8. */ + +EXPORT StringBuf uri_to_display(const char * uri) +{ + if (!strncmp(uri, "stdin://", 8)) + return str_copy(_("Standard input")); + if (!strncmp(uri, "cdda://?", 8)) + return str_printf(_("Audio CD, track %s"), uri + 8); + + StringBuf buf = str_to_utf8(str_decode_percent(uri)); + if (!buf) + return str_copy(_("(character encoding error)")); + + if (!strncmp(buf, URI_PREFIX, URI_PREFIX_LEN)) + { + buf.remove(0, URI_PREFIX_LEN); + return filename_contract(filename_normalize(std::move(buf))); + } + + return buf; +} + +#undef URI_PREFIX +#undef URI_PREFIX_LEN + +EXPORT void uri_parse(const char * uri, const char ** base_p, + const char ** ext_p, const char ** sub_p, int * isub_p) +{ + const char * end = uri + strlen(uri); + const char *base, *ext, *sub, *c; + int isub = 0; + char junk; + + if ((c = strrchr(uri, '/'))) + base = c + 1; + else + base = end; + + if ((c = strrchr(base, '?')) && sscanf(c + 1, "%d%c", &isub, &junk) == 1) + sub = c; + else + sub = end; + + if ((c = strrchr(base, '.')) && c < sub) + ext = c; + else + ext = sub; + + if (base_p) + *base_p = base; + if (ext_p) + *ext_p = ext; + if (sub_p) + *sub_p = sub; + if (isub_p) + *isub_p = isub; +} + +EXPORT StringBuf uri_get_scheme(const char * uri) +{ + const char * delim = strstr(uri, "://"); + return delim ? str_copy(uri, delim - uri) : StringBuf(); +} + +EXPORT StringBuf uri_get_extension(const char * uri) +{ + const char * ext; + uri_parse(uri, nullptr, &ext, nullptr, nullptr); + + if (ext[0] != '.') + return StringBuf(); + + ext++; // skip period + + // remove subtunes and HTTP query strings + const char * qmark = strchr(ext, '?'); + return str_copy(ext, qmark ? qmark - ext : -1); +} + +EXPORT StringBuf uri_get_display_base(const char * uri) +{ + const char *base, *ext; + uri_parse(uri, &base, &ext, nullptr, nullptr); + + if (ext > base) + return str_to_utf8(str_decode_percent(base, ext - base)); + + return StringBuf(); +} + +/* Constructs a full URI given: + * 1. path: one of the following: + * a. a full URI (returned unchanged) + * b. an absolute filename (in UTF-8 or the system locale) + * c. a relative path (character set detected according to user settings) + * 2. reference: the full URI of the playlist containing <path> */ + +EXPORT StringBuf uri_construct(const char * path, const char * reference) +{ + /* URI */ + if (strstr(path, "://")) + return str_copy(path); + + /* absolute filename */ +#ifdef _WIN32 + if (path[0] && path[1] == ':' && IS_SEP(path[2])) +#else + if (path[0] == '/') +#endif + return filename_to_uri(path); + + /* relative path */ + const char * slash = strrchr(reference, '/'); + if (!slash) + return StringBuf(); + + StringBuf buf = str_to_utf8(path, -1); + if (!buf) + return StringBuf(); + + if (aud_get_bool("convert_backslash")) + str_replace_char(buf, '\\', '/'); + + buf = str_encode_percent(buf); + buf.insert(0, reference, slash + 1 - reference); + return buf.settle(); +} + +/* Basically the reverse of uri_construct(). + * First try to split off a relative path (if so configured). + * Failing that, try to convert to a local filename. + * Failing that, return the URI as-is. + * + * All output is UTF-8 for portability. + * + * Parameters: + * 1. uri: the full URI of a song file + * 2. reference: the full URI of the playlist being written */ + +EXPORT StringBuf uri_deconstruct(const char * uri, const char * reference) +{ + if (aud_get_bool("export_relative_paths")) + { + const char * slash = strrchr(reference, '/'); + if (slash && !strncmp(uri, reference, slash + 1 - reference)) + { + StringBuf path = + str_to_utf8(str_decode_percent(uri + (slash + 1 - reference))); + if (path) + return path; + } + } + + StringBuf filename = uri_to_filename(uri, false); + if (filename) + return filename; + + return str_copy(uri); +} + +/* Like strcasecmp, but orders numbers correctly (2 before 10). */ +/* Non-ASCII characters are treated exactly as is. */ +/* Handles nullptr gracefully. */ + +EXPORT int str_compare(const char * ap, const char * bp) +{ + if (!ap) + return bp ? -1 : 0; + if (!bp) + return 1; + + unsigned char a = *ap++, b = *bp++; + for (; a || b; a = *ap++, b = *bp++) + { + if (a > '9' || b > '9' || a < '0' || b < '0') + { + if (a <= 'Z' && a >= 'A') + a += 'a' - 'A'; + if (b <= 'Z' && b >= 'A') + b += 'a' - 'A'; + + if (a > b) + return 1; + if (a < b) + return -1; + } + else + { + int x = a - '0'; + for (; (a = *ap) <= '9' && a >= '0'; ap++) + x = 10 * x + (a - '0'); + + int y = b - '0'; + for (; (b = *bp) >= '0' && b <= '9'; bp++) + y = 10 * y + (b - '0'); + + if (x > y) + return 1; + if (x < y) + return -1; + } + } + + return 0; +} + +/* Decodes percent-encoded strings, then compares them with str_compare. */ + +EXPORT int str_compare_encoded(const char * ap, const char * bp) +{ + if (!ap) + return bp ? -1 : 0; + if (!bp) + return 1; + + unsigned char a = *ap++, b = *bp++; + for (; a || b; a = *ap++, b = *bp++) + { + if (a == '%' && ap[0] && ap[1]) + { + a = (FROM_HEX(ap[0]) << 4) | FROM_HEX(ap[1]); + ap += 2; + } + if (b == '%' && bp[0] && bp[1]) + { + b = (FROM_HEX(bp[0]) << 4) | FROM_HEX(bp[1]); + bp += 2; + } + + if (a > '9' || b > '9' || a < '0' || b < '0') + { + if (a <= 'Z' && a >= 'A') + a += 'a' - 'A'; + if (b <= 'Z' && b >= 'A') + b += 'a' - 'A'; + + if (a > b) + return 1; + if (a < b) + return -1; + } + else + { + int x = a - '0'; + for (; (a = *ap) <= '9' && a >= '0'; ap++) + x = 10 * x + (a - '0'); + + int y = b - '0'; + for (; (b = *bp) >= '0' && b <= '9'; bp++) + y = 10 * y + (b - '0'); + + if (x > y) + return 1; + if (x < y) + return -1; + } + } + + return 0; +} + +EXPORT Index<String> str_list_to_index(const char * list, const char * delims) +{ + char dmap[256] = {0}; + + for (; *delims; delims++) + dmap[(unsigned char)(*delims)] = 1; + + Index<String> index; + const char * word = nullptr; + + for (; *list; list++) + { + if (dmap[(unsigned char)(*list)]) + { + if (word) + { + index.append(String(str_copy(word, list - word))); + word = nullptr; + } + } + else + { + if (!word) + { + word = list; + } + } + } + + if (word) + index.append(String(word)); + + return index; +} + +EXPORT StringBuf index_to_str_list(const Index<String> & index, + const char * sep) +{ + StringBuf str(-1); + char * set = str; + int left = str.len(); + int seplen = strlen(sep); + + for (const String & s : index) + { + int len = strlen(s); + if (len + seplen > left) + throw std::bad_alloc(); + + if (set > str) + { + memcpy(set, sep, seplen); + + set += seplen; + left -= seplen; + } + + memcpy(set, s, len); + + set += len; + left -= len; + } + + str.resize(set - str); + return str; +} + +/* + * Routines to convert numbers between string and binary representations. + * + * Goals: + * + * - Accuracy, meaning that we can convert back and forth between string and + * binary without the number changing slightly each time. + * - Consistency, meaning that we get the same results no matter what + * architecture or locale we have to deal with. + * - Readability, meaning that the number one is rendered "1", not "1.000". + * + * Values between -1,000,000,000 and 1,000,000,000 (inclusive) are guaranteed to + * have an accuracy of 6 decimal places. + */ + +static unsigned str_to_uint(const char * string, const char ** end = nullptr, + const char * stop = nullptr) +{ + unsigned val = 0; + for (char c; string != stop && (c = *string) >= '0' && c <= '9'; string++) + val = val * 10 + (c - '0'); + + if (end) + *end = string; + + return val; +} + +static int digits_for(unsigned val) +{ + int digits = 1; + + for (; val >= 1000; val /= 1000) + digits += 3; + for (; val >= 10; val /= 10) + digits++; + + return digits; +} + +static void uint_to_str(unsigned val, char * buf, int digits) +{ + for (char * rev = buf + digits; rev > buf; val /= 10) + *(--rev) = '0' + val % 10; +} + +EXPORT int str_to_int(const char * string) +{ + bool neg = (string[0] == '-'); + if (neg || string[0] == '+') + string++; + + unsigned val = str_to_uint(string); + return neg ? -val : val; +} + +EXPORT double str_to_double(const char * string) +{ + bool neg = (string[0] == '-'); + if (neg || string[0] == '+') + string++; + + const char * p; + double val = str_to_uint(string, &p); + + if (*(p++) == '.') + { + const char * end; + double decimal = str_to_uint(p, &end, p + MAX_POW10); + val += decimal / int_pow10[end - p]; + } + + return neg ? -val : val; +} + +EXPORT void str_insert_int(StringBuf & string, int pos, int val) +{ + bool neg = (val < 0); + unsigned absval = neg ? -val : val; + + int digits = digits_for(absval); + int len = (neg ? 1 : 0) + digits; + char * set = string.insert(pos, nullptr, len); + + if (neg) + *(set++) = '-'; + + uint_to_str(absval, set, digits); +} + +EXPORT void str_insert_double(StringBuf & string, int pos, double val) +{ + bool neg = (val < 0); + if (neg) + val = -val; + + unsigned i = floor(val); + unsigned f = round((val - i) * 1000000); + + if (f == 1000000) + { + i++; + f = 0; + } + + int decimals = f ? 6 : 0; + for (; decimals && !(f % 10); f /= 10) + decimals--; + + int digits = digits_for(i); + int len = (neg ? 1 : 0) + digits + (decimals ? 1 : 0) + decimals; + char * set = string.insert(pos, nullptr, len); + + if (neg) + *(set++) = '-'; + + uint_to_str(i, set, digits); + + if (decimals) + { + set += digits; + *(set++) = '.'; + uint_to_str(f, set, decimals); + } +} + +EXPORT StringBuf int_to_str(int val) +{ + StringBuf buf; + str_insert_int(buf, 0, val); + return buf; +} + +EXPORT StringBuf double_to_str(double val) +{ + StringBuf buf; + str_insert_double(buf, 0, val); + return buf; +} + +EXPORT bool str_to_int_array(const char * string, int * array, int count) +{ + Index<String> index = str_list_to_index(string, ", "); + + if (index.len() != count) + return false; + + for (int i = 0; i < count; i++) + array[i] = str_to_int(index[i]); + + return true; +} + +EXPORT StringBuf int_array_to_str(const int * array, int count) +{ + Index<String> index; + + for (int i = 0; i < count; i++) + index.append(String(int_to_str(array[i]))); + + return index_to_str_list(index, ","); +} + +EXPORT bool str_to_double_array(const char * string, double * array, int count) +{ + Index<String> index = str_list_to_index(string, ", "); + + if (index.len() != count) + return false; + + for (int i = 0; i < count; i++) + array[i] = str_to_double(index[i]); + + return true; +} + +EXPORT StringBuf double_array_to_str(const double * array, int count) +{ + Index<String> index; + + for (int i = 0; i < count; i++) + index.append(String(double_to_str(array[i]))); + + return index_to_str_list(index, ","); +} + +EXPORT StringBuf str_format_time(int64_t milliseconds) +{ + bool neg = milliseconds < 0; + + if (neg) + milliseconds *= -1; + + int hours = milliseconds / 3600000; + int minutes = milliseconds / 60000; + int seconds = (milliseconds / 1000) % 60; + + if (hours && aud_get_bool("show_hours")) + return str_printf("%s%d:%02d:%02d", neg ? "- " : "", hours, + minutes % 60, seconds); + else + { + bool zero = aud_get_bool("leading_zero"); + return str_printf(zero ? "%s%02d:%02d" : "%s%d:%02d", neg ? "- " : "", + minutes, seconds); + } +} diff --git a/src/libaudcore/audstrings.h b/src/libaudcore/audstrings.h new file mode 100644 index 0000000..ccd0439 --- /dev/null +++ b/src/libaudcore/audstrings.h @@ -0,0 +1,130 @@ +/* + * audstrings.h + * Copyright 2009-2012 John Lindgren and Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_STRINGS_H +#define LIBAUDCORE_STRINGS_H + +#include <stdarg.h> +#include <stdint.h> + +#include <initializer_list> + +#include <libaudcore/index.h> +#include <libaudcore/objects.h> + +int strcmp_safe(const char * a, const char * b, int len = -1); +int strcmp_nocase(const char * a, const char * b, int len = -1); +int strlen_bounded(const char * s, int len = -1); + +StringBuf str_copy(const char * s, int len = -1); +StringBuf str_concat(const std::initializer_list<const char *> & strings); +#ifdef _WIN32 +StringBuf str_printf(const char * format, ...) + __attribute__((__format__(gnu_printf, 1, 2))); +void str_append_printf(StringBuf & str, const char * format, ...) + __attribute__((__format__(gnu_printf, 2, 3))); +#else +StringBuf str_printf(const char * format, ...) + __attribute__((__format__(__printf__, 1, 2))); +void str_append_printf(StringBuf & str, const char * format, ...) + __attribute__((__format__(__printf__, 2, 3))); +#endif +StringBuf str_vprintf(const char * format, va_list args); +void str_append_vprintf(StringBuf & str, const char * format, va_list args); + +bool str_has_prefix_nocase(const char * str, const char * prefix); +bool str_has_suffix_nocase(const char * str, const char * suffix); + +unsigned str_calc_hash(const char * str); + +const char * strstr_nocase(const char * haystack, const char * needle); +const char * strstr_nocase_utf8(const char * haystack, const char * needle); + +static inline char * strstr_nocase(char * haystack, const char * needle) +{ + return (char *)strstr_nocase((const char *)haystack, needle); +} +static inline char * strstr_nocase_utf8(char * haystack, const char * needle) +{ + return (char *)strstr_nocase_utf8((const char *)haystack, needle); +} + +StringBuf str_tolower(const char * str); +StringBuf str_tolower_utf8(const char * str); +StringBuf str_toupper(const char * str); +StringBuf str_toupper_utf8(const char * str); + +void str_replace_char(char * string, char old_c, char new_c); + +StringBuf str_decode_percent(const char * str, int len = -1); +StringBuf str_encode_percent(const char * str, int len = -1); + +StringBuf str_convert(const char * str, int len, const char * from_charset, + const char * to_charset); +StringBuf str_from_locale(const char * str, int len = -1); +StringBuf str_to_locale(const char * str, int len = -1); + +/* Requires: aud_init() */ +StringBuf str_to_utf8(const char * str, + int len); // no "len = -1" to avoid ambiguity +StringBuf str_to_utf8(StringBuf && str); + +StringBuf filename_normalize(StringBuf && filename); +StringBuf filename_contract(StringBuf && filename); +StringBuf filename_expand(StringBuf && filename); +StringBuf filename_get_parent(const char * filename); +StringBuf filename_get_base(const char * filename); +StringBuf filename_build(const std::initializer_list<const char *> & elems); +StringBuf filename_to_uri(const char * filename); +StringBuf uri_to_filename(const char * uri, bool use_locale = true); + +void uri_parse(const char * uri, const char ** base_p, const char ** ext_p, + const char ** sub_p, int * isub_p); + +StringBuf uri_get_scheme(const char * uri); +StringBuf uri_get_extension(const char * uri); + +/* Requires: aud_init() */ +StringBuf uri_to_display(const char * uri); +StringBuf uri_get_display_base(const char * uri); +StringBuf uri_construct(const char * path, const char * reference); +StringBuf uri_deconstruct(const char * uri, const char * reference); + +int str_compare(const char * a, const char * b); +int str_compare_encoded(const char * a, const char * b); + +Index<String> str_list_to_index(const char * list, const char * delims); +StringBuf index_to_str_list(const Index<String> & index, const char * sep); + +int str_to_int(const char * string); +double str_to_double(const char * string); +void str_insert_int(StringBuf & string, int pos, int val); +void str_insert_double(StringBuf & string, int pos, double val); +StringBuf int_to_str(int val); +StringBuf double_to_str(double val); + +bool str_to_int_array(const char * string, int * array, int count); +StringBuf int_array_to_str(const int * array, int count); +bool str_to_double_array(const char * string, double * array, int count); +StringBuf double_array_to_str(const double * array, int count); + +/* Requires: aud_init() */ +StringBuf str_format_time(int64_t milliseconds); + +#endif /* LIBAUDCORE_STRINGS_H */ diff --git a/src/libaudcore/charset.cc b/src/libaudcore/charset.cc new file mode 100644 index 0000000..542225f --- /dev/null +++ b/src/libaudcore/charset.cc @@ -0,0 +1,213 @@ +/* + * charset.c + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "audstrings.h" +#include "internal.h" + +#include <errno.h> +#include <iconv.h> +#include <string.h> + +#include <new> + +#include <glib.h> + +#include "libguess/libguess.h" + +#include "hook.h" +#include "index.h" +#include "runtime.h" +#include "threads.h" + +EXPORT StringBuf str_convert(const char * str, int len, + const char * from_charset, const char * to_charset) +{ + iconv_t conv = iconv_open(to_charset, from_charset); + if (conv == (iconv_t)-1) + return StringBuf(); + + if (len < 0) + len = strlen(str); + + StringBuf buf(-1); + + size_t inbytesleft = len; + size_t outbytesleft = buf.len(); + ICONV_CONST char * in = (ICONV_CONST char *)str; + char * out = buf; + + errno = 0; + size_t ret = iconv(conv, &in, &inbytesleft, &out, &outbytesleft); + + if (ret == (size_t)-1 && errno == E2BIG) + throw std::bad_alloc(); + + iconv_close(conv); + + if (ret == (size_t)-1 || inbytesleft) + return StringBuf(); + + buf.resize(buf.len() - outbytesleft); + return buf; +} + +static void whine_locale(const char * str, int len, const char * dir, + const char * charset) +{ + if (len < 0) + AUDWARN("Cannot convert %s locale (%s): %s\n", dir, charset, str); + else + AUDWARN("Cannot convert %s locale (%s): %.*s\n", dir, charset, len, + str); +} + +EXPORT StringBuf str_from_locale(const char * str, int len) +{ + const char * charset; + + if (g_get_charset(&charset)) + { + /* locale is UTF-8 */ + if (!g_utf8_validate(str, len, nullptr)) + { + whine_locale(str, len, "from", "UTF-8"); + return StringBuf(); + } + + return str_copy(str, len); + } + else + { + StringBuf utf8 = str_convert(str, len, charset, "UTF-8"); + if (!utf8) + whine_locale(str, len, "from", charset); + + return utf8; + } +} + +EXPORT StringBuf str_to_locale(const char * str, int len) +{ + const char * charset; + + if (g_get_charset(&charset)) + { + /* locale is UTF-8 */ + return str_copy(str, len); + } + else + { + StringBuf local = str_convert(str, len, "UTF-8", charset); + if (!local) + whine_locale(str, len, "to", charset); + + return local; + } +} + +static aud::spinlock_rw settings_lock; +static String detect_region; +static Index<String> fallback_charsets; + +static void set_charsets(const char * region, const char * fallbacks) +{ + auto wr = settings_lock.write(); + + detect_region = String(region); + + if (fallbacks) + fallback_charsets = str_list_to_index(fallbacks, ", "); + else + fallback_charsets.clear(); +} + +static StringBuf convert_to_utf8(const char * str, int len) +{ + auto rd = settings_lock.read(); + + if (len < 0) + len = strlen(str); + + if (detect_region) + { + /* prefer libguess-detected charset */ + const char * detected = + libguess_determine_encoding(str, len, detect_region); + if (detected) + { + StringBuf utf8 = str_convert(str, len, detected, "UTF-8"); + if (utf8) + return utf8; + } + } + + /* try user-configured fallbacks */ + for (const String & fallback : fallback_charsets) + { + StringBuf utf8 = str_convert(str, len, fallback, "UTF-8"); + if (utf8) + return utf8; + } + + /* try system locale last (this one will print a warning if it fails) */ + return str_from_locale(str, len); +} + +EXPORT StringBuf str_to_utf8(const char * str, int len) +{ + /* check whether already UTF-8 */ + if (g_utf8_validate(str, len, nullptr)) + return str_copy(str, len); + + return convert_to_utf8(str, len); +} + +EXPORT StringBuf str_to_utf8(StringBuf && str) +{ + /* check whether already UTF-8 */ + if (g_utf8_validate(str, str.len(), nullptr)) + return std::move(str); + + str = convert_to_utf8(str, str.len()); + return str.settle(); +} + +static void chardet_update(void * = nullptr, void * = nullptr) +{ + String region = aud_get_str("chardet_detector"); + String fallbacks = aud_get_str("chardet_fallback"); + + set_charsets(region[0] ? (const char *)region : nullptr, fallbacks); +} + +void chardet_init() +{ + chardet_update(); + + hook_associate("set chardet_detector", chardet_update, nullptr); + hook_associate("set chardet_fallback", chardet_update, nullptr); +} + +void chardet_cleanup() +{ + hook_dissociate("set chardet_detector", chardet_update); + hook_dissociate("set chardet_fallback", chardet_update); + + set_charsets(nullptr, nullptr); +} diff --git a/src/libaudcore/config.cc b/src/libaudcore/config.cc new file mode 100644 index 0000000..e39b4d5 --- /dev/null +++ b/src/libaudcore/config.cc @@ -0,0 +1,425 @@ +/* + * config.c + * Copyright 2011-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "internal.h" +#include "runtime.h" + +#include <assert.h> +#include <string.h> + +#include "audstrings.h" +#include "hook.h" +#include "inifile.h" +#include "multihash.h" +#include "runtime.h" +#include "vfs.h" + +#define DEFAULT_SECTION "audacious" + +static const char * const core_defaults[] = { + /* clang-format off */ + /* general */ + "advance_on_delete", "FALSE", + "always_resume_paused", "TRUE", + "clear_playlist", "TRUE", + "open_to_temporary", "TRUE", + "recurse_folders", "TRUE", + "resume_playback_on_startup", "TRUE", + "show_interface", "TRUE", + + /* equalizer */ + "eqpreset_default_file", "", + "eqpreset_extension", "", + "equalizer_active", "FALSE", + "equalizer_bands", "0,0,0,0,0,0,0,0,0,0", + "equalizer_preamp", "0", + + /* info popup / info window */ + "cover_name_exclude", "back", + "cover_name_include", "album,cover,front,folder", + "filepopup_delay", "5", + "filepopup_showprogressbar", "FALSE", + "recurse_for_cover", "FALSE", + "recurse_for_cover_depth", "0", + "show_filepopup_for_tuple", "TRUE", + "use_file_cover", "FALSE", + + /* network */ + "net_buffer_kb", "128", + "save_url_history", "TRUE", + "socks_proxy", "FALSE", + "socks_type", "0", + "use_proxy", "FALSE", + "use_proxy_auth", "FALSE", + + /* output */ + "default_gain", "0", + "enable_replay_gain", "TRUE", + "enable_clipping_prevention", "TRUE", + "output_bit_depth", "-1", + "output_buffer_size", "500", + "record", "FALSE", + "record_stream", aud::numeric_string<(int) OutputStream::AfterReplayGain>::str, + "replay_gain_mode", aud::numeric_string<(int) ReplayGainMode::Track>::str, + "replay_gain_preamp", "0", + "soft_clipping", "FALSE", + "software_volume_control", "FALSE", + "sw_volume_left", "100", + "sw_volume_right", "100", + "volume_delta", "5", + + /* playback */ + "album_shuffle", "FALSE", + "no_playlist_advance", "FALSE", + "repeat", "FALSE", + "shuffle", "FALSE", + "step_size", "5", + "stop_after_current_song", "FALSE", + + /* playlist */ + "chardet_fallback", "ISO-8859-1", +#ifdef _WIN32 + "convert_backslash", "TRUE", +#else + "convert_backslash", "FALSE", +#endif + "export_relative_paths", "TRUE", + "folders_in_playlist", "FALSE", + "generic_title_format", "${?artist:${artist} - }${?album:${album} - }${title}", + "leading_zero", "FALSE", + "show_hours", "TRUE", + "metadata_fallbacks", "TRUE", + "metadata_on_play", "FALSE", + "show_numbers_in_pl", "FALSE", + "slow_probe", "FALSE", + /* clang-format on */ + nullptr}; + +enum OpType +{ + OP_IS_DEFAULT, + OP_GET, + OP_SET, + OP_SET_NO_FLAG, + OP_CLEAR, + OP_CLEAR_NO_FLAG +}; + +struct ConfigItem +{ + String section; + String key; + String value; +}; + +struct ConfigNode; + +// combined Data and Operation class +struct ConfigOp +{ + OpType type; + const char * section; + const char * key; + String value; + unsigned hash; + bool result; + + ConfigNode * add(const ConfigOp *); + bool found(ConfigNode * node); +}; + +struct ConfigNode : public MultiHash::Node, public ConfigItem +{ + bool match(const ConfigOp * op) const + { + return !strcmp(section, op->section) && !strcmp(key, op->key); + } +}; + +typedef MultiHash_T<ConfigNode, ConfigOp> ConfigTable; + +static ConfigTable s_defaults, s_config; +static volatile bool s_modified; + +ConfigNode * ConfigOp::add(const ConfigOp *) +{ + switch (type) + { + case OP_IS_DEFAULT: + result = !value[0]; /* empty string is default */ + return nullptr; + + case OP_SET: + result = true; + s_modified = true; + // fall-through + + case OP_SET_NO_FLAG: + { + ConfigNode * node = new ConfigNode; + node->section = String(section); + node->key = String(key); + node->value = value; + return node; + } + + default: + return nullptr; + } +} + +bool ConfigOp::found(ConfigNode * node) +{ + switch (type) + { + case OP_IS_DEFAULT: + result = !strcmp(node->value, value); + return false; + + case OP_GET: + value = node->value; + return false; + + case OP_SET: + result = !!strcmp(node->value, value); + if (result) + s_modified = true; + // fall-through + + case OP_SET_NO_FLAG: + node->value = value; + return false; + + case OP_CLEAR: + result = true; + s_modified = true; + // fall-through + + case OP_CLEAR_NO_FLAG: + delete node; + return true; + + default: + return false; + } +} + +static bool config_op_run(ConfigOp & op, ConfigTable & table) +{ + if (!op.hash) + op.hash = str_calc_hash(op.section) + str_calc_hash(op.key); + + op.result = false; + table.lookup(&op, op.hash, op); + return op.result; +} + +class ConfigParser : public IniParser +{ +private: + String section; + + void handle_heading(const char * heading) { section = String(heading); } + + void handle_entry(const char * key, const char * value) + { + if (!section) + return; + + ConfigOp op = {OP_SET_NO_FLAG, section, key, String(value)}; + config_op_run(op, s_config); + } +}; + +void config_load() +{ + StringBuf path = filename_build({aud_get_path(AudPath::UserDir), "config"}); + if (VFSFile::test_file(path, VFS_EXISTS)) + { + VFSFile file(path, "r"); + if (file) + ConfigParser().parse(file); + } + + aud_config_set_defaults(nullptr, core_defaults); + + /* migrate from previous versions */ + if (aud_get_bool("replay_gain_album")) + { + aud_set_str("replay_gain_album", ""); + aud_set_int("replay_gain_mode", (int)ReplayGainMode::Album); + } + + double step_size = aud_get_double("gtkui", "step_size"); + if (step_size > 0) + { + aud_set_int("step_size", (int)step_size); + aud_set_str("gtkui", "step_size", ""); + } + + int volume_delta = aud_get_int("statusicon", "volume_delta"); + if (volume_delta > 0) + { + aud_set_int("volume_delta", volume_delta); + aud_set_str("statusicon", "volume_delta", ""); + } +} + +void config_save() +{ + if (!s_modified) + return; + + Index<ConfigItem> list; + + auto add_to_list = [&](ConfigNode * node) { + list.append(*node); + return false; + }; + auto finish = []() { + s_modified = false; // must be inside MultiHash lock + }; + + s_config.iterate(add_to_list, finish); + + list.sort([](const ConfigItem & a, const ConfigItem & b) { + if (a.section == b.section) + return strcmp(a.key, b.key); + else + return strcmp(a.section, b.section); + }); + + String current_heading; + + VFSFile file(filename_build({aud_get_path(AudPath::UserDir), "config"}), + "w"); + if (!file) + goto FAILED; + + for (const ConfigItem & item : list) + { + if (item.section != current_heading) + { + if (!inifile_write_heading(file, item.section)) + goto FAILED; + + current_heading = item.section; + } + + if (!inifile_write_entry(file, item.key, item.value)) + goto FAILED; + } + + if (file.fflush() < 0) + goto FAILED; + + return; + +FAILED: + AUDWARN("Error saving configuration.\n"); +} + +EXPORT void aud_config_set_defaults(const char * section, + const char * const * entries) +{ + if (!section) + section = DEFAULT_SECTION; + + while (1) + { + const char * name = *entries++; + const char * value = *entries++; + if (!name || !value) + break; + + ConfigOp op = {OP_SET_NO_FLAG, section, name, String(value)}; + config_op_run(op, s_defaults); + } +} + +void config_cleanup() +{ + s_config.clear(); + s_defaults.clear(); +} + +EXPORT void aud_set_str(const char * section, const char * name, + const char * value) +{ + assert(name && value); + + ConfigOp op = {OP_IS_DEFAULT, section ? section : DEFAULT_SECTION, name, + String(value)}; + bool is_default = config_op_run(op, s_defaults); + + op.type = is_default ? OP_CLEAR : OP_SET; + bool changed = config_op_run(op, s_config); + + if (changed && !section) + event_queue(str_concat({"set ", name}), nullptr); +} + +EXPORT String aud_get_str(const char * section, const char * name) +{ + assert(name); + + ConfigOp op = {OP_GET, section ? section : DEFAULT_SECTION, name}; + config_op_run(op, s_config); + + if (!op.value) + config_op_run(op, s_defaults); + + return op.value ? op.value : String(""); +} + +EXPORT void aud_set_bool(const char * section, const char * name, bool value) +{ + aud_set_str(section, name, value ? "TRUE" : "FALSE"); +} + +EXPORT bool aud_get_bool(const char * section, const char * name) +{ + return !strcmp(aud_get_str(section, name), "TRUE"); +} + +EXPORT void aud_toggle_bool(const char * section, const char * name) +{ + aud_set_bool(section, name, !aud_get_bool(section, name)); +} + +EXPORT void aud_set_int(const char * section, const char * name, int value) +{ + aud_set_str(section, name, int_to_str(value)); +} + +EXPORT int aud_get_int(const char * section, const char * name) +{ + return str_to_int(aud_get_str(section, name)); +} + +EXPORT void aud_set_double(const char * section, const char * name, + double value) +{ + aud_set_str(section, name, double_to_str(value)); +} + +EXPORT double aud_get_double(const char * section, const char * name) +{ + return str_to_double(aud_get_str(section, name)); +} diff --git a/src/libaudcore/cue-cache.cc b/src/libaudcore/cue-cache.cc new file mode 100644 index 0000000..f568f7c --- /dev/null +++ b/src/libaudcore/cue-cache.cc @@ -0,0 +1,94 @@ +/* + * cue-cache.cc + * Copyright 2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "cue-cache.h" +#include "multihash.h" +#include "playlist-internal.h" +#include "threads.h" + +enum NodeState +{ + NotLoaded, + Loading, + Loaded +}; + +struct CueCacheNode +{ + Index<PlaylistAddItem> items; + NodeState state = NotLoaded; + int refcount = 0; +}; + +static SimpleHash<String, CueCacheNode> cache; +static aud::mutex mutex; +static aud::condvar cond; + +CueCacheRef::CueCacheRef(const char * filename) : m_filename(filename) +{ + auto mh = mutex.take(); + + m_node = cache.lookup(m_filename); + if (!m_node) + m_node = cache.add(m_filename, CueCacheNode()); + + m_node->refcount++; +} + +CueCacheRef::~CueCacheRef() +{ + auto mh = mutex.take(); + + m_node->refcount--; + if (!m_node->refcount) + cache.remove(m_filename); +} + +const Index<PlaylistAddItem> & CueCacheRef::load() +{ + auto mh = mutex.take(); + String title; // not used + + switch (m_node->state) + { + case NotLoaded: + // load the cuesheet in this thread + m_node->state = Loading; + mh.unlock(); + playlist_load(m_filename, title, m_node->items); + mh.lock(); + + m_node->state = Loaded; + cond.notify_all(); + break; + + case Loading: + // wait for cuesheet to load in another thread + while (m_node->state != Loaded) + cond.wait(mh); + + break; + + case Loaded: + // cuesheet already loaded + break; + } + + return m_node->items; +} diff --git a/src/libaudcore/cue-cache.h b/src/libaudcore/cue-cache.h new file mode 100644 index 0000000..c5af486 --- /dev/null +++ b/src/libaudcore/cue-cache.h @@ -0,0 +1,41 @@ +/* + * cue-cache.h + * Copyright 2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_CUE_CACHE_H +#define LIBAUDCORE_CUE_CACHE_H + +#include "index.h" +#include "tuple.h" + +struct CueCacheNode; + +class CueCacheRef +{ +public: + CueCacheRef(const char * filename); + ~CueCacheRef(); + + const Index<PlaylistAddItem> & load(); + +private: + String m_filename; + CueCacheNode * m_node; +}; + +#endif // LIBAUDCORE_CUE_CACHE_H diff --git a/src/libaudcore/drct.cc b/src/libaudcore/drct.cc new file mode 100644 index 0000000..592f8e8 --- /dev/null +++ b/src/libaudcore/drct.cc @@ -0,0 +1,279 @@ +/* + * drct.c + * Copyright 2009-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "drct.h" + +#include "hook.h" +#include "i18n.h" +#include "interface.h" +#include "internal.h" +#include "playlist-internal.h" +#include "plugins-internal.h" +#include "runtime.h" +#include "tuple.h" + +/* --- PLAYBACK CONTROL --- */ + +EXPORT void aud_drct_play() +{ + if (aud_drct_get_playing()) + { + if (aud_drct_get_paused()) + aud_drct_pause(); + else + { + int a, b; + aud_drct_get_ab_repeat(a, b); + aud_drct_seek(aud::max(a, 0)); + } + } + else + { + auto playlist = Playlist::active_playlist(); + playlist.set_position(playlist.get_position()); + playlist.start_playback(); + } +} + +EXPORT void aud_drct_play_pause() +{ + if (aud_drct_get_playing()) + aud_drct_pause(); + else + aud_drct_play(); +} + +EXPORT int aud_drct_get_position() +{ + return Playlist::playing_playlist().get_position(); +} + +EXPORT String aud_drct_get_filename() +{ + auto playlist = Playlist::playing_playlist(); + return playlist.entry_filename(playlist.get_position()); +} + +/* --- RECORDING CONTROL --- */ + +/* The recording plugin is currently hard-coded to FileWriter. Someday + * aud_drct_set_record_plugin() may be added. */ + +static PluginHandle * record_plugin; + +static bool record_plugin_watcher(PluginHandle *, void *) +{ + if (!aud_drct_get_record_enabled()) + aud_set_bool("record", false); + + hook_call("enable record", nullptr); + return true; +} + +static void validate_record_setting(void *, void *) +{ + if (aud_get_bool("record") && !aud_drct_get_record_enabled()) + { + /* User attempted to start recording without a recording plugin enabled. + * This is probably not the best response, but better than nothing. */ + aud_set_bool("record", false); + aud_ui_show_error(_("Stream recording must be configured in Audio " + "Settings before it can be used.")); + } +} + +void record_init() +{ + // when building under Meson, the plugin may be libfilewriter.so. + auto plugin = aud_plugin_lookup_basename("filewriter"); + if (!plugin) + plugin = aud_plugin_lookup_basename("libfilewriter"); + + if (plugin && aud_plugin_get_type(plugin) == PluginType::Output) + { + record_plugin = plugin; + aud_plugin_add_watch(plugin, record_plugin_watcher, nullptr); + } + + if (!aud_drct_get_record_enabled()) + aud_set_bool("record", false); + + hook_associate("set record", validate_record_setting, nullptr); +} + +void record_cleanup() +{ + hook_dissociate("set record", validate_record_setting); + + if (record_plugin) + { + aud_plugin_remove_watch(record_plugin, record_plugin_watcher, nullptr); + record_plugin = nullptr; + } +} + +EXPORT PluginHandle * aud_drct_get_record_plugin() +{ + /* recording is disabled when FileWriter is the primary output plugin */ + if (!record_plugin || + plugin_get_enabled(record_plugin) == PluginEnabled::Primary) + return nullptr; + + return record_plugin; +} + +EXPORT bool aud_drct_get_record_enabled() +{ + return (record_plugin && + plugin_get_enabled(record_plugin) == PluginEnabled::Secondary); +} + +EXPORT bool aud_drct_enable_record(bool enable) +{ + if (!record_plugin || + plugin_get_enabled(record_plugin) == PluginEnabled::Primary) + return false; + + return plugin_enable_secondary(record_plugin, enable); +} + +/* --- VOLUME CONTROL --- */ + +EXPORT int aud_drct_get_volume_main() +{ + StereoVolume volume = aud_drct_get_volume(); + return aud::max(volume.left, volume.right); +} + +EXPORT void aud_drct_set_volume_main(int volume) +{ + StereoVolume old = aud_drct_get_volume(); + int main = aud::max(old.left, old.right); + + if (main > 0) + aud_drct_set_volume({aud::rescale(old.left, main, volume), + aud::rescale(old.right, main, volume)}); + else + aud_drct_set_volume({volume, volume}); +} + +EXPORT int aud_drct_get_volume_balance() +{ + StereoVolume volume = aud_drct_get_volume(); + + if (volume.left == volume.right) + return 0; + else if (volume.left > volume.right) + return -100 + aud::rescale(volume.right, volume.left, 100); + else + return 100 - aud::rescale(volume.left, volume.right, 100); +} + +EXPORT void aud_drct_set_volume_balance(int balance) +{ + int main = aud_drct_get_volume_main(); + + if (balance < 0) + aud_drct_set_volume({main, aud::rescale(main, 100, 100 + balance)}); + else + aud_drct_set_volume({aud::rescale(main, 100, 100 - balance), main}); +} + +/* --- PLAYLIST CONTROL --- */ + +EXPORT void aud_drct_pl_next() +{ + PlaylistEx playlist = Playlist::playing_playlist(); + if (playlist == Playlist()) + playlist = Playlist::active_playlist(); + + playlist.next_song(aud_get_bool("repeat")); +} + +EXPORT void aud_drct_pl_next_album() +{ + PlaylistEx playlist = Playlist::playing_playlist(); + if (playlist == Playlist()) + playlist = Playlist::active_playlist(); + + playlist.next_album(aud_get_bool("repeat")); +} + +EXPORT void aud_drct_pl_prev() +{ + PlaylistEx playlist = Playlist::playing_playlist(); + if (playlist == Playlist()) + playlist = Playlist::active_playlist(); + + playlist.prev_song(); +} + +EXPORT void aud_drct_pl_prev_album() +{ + PlaylistEx playlist = Playlist::playing_playlist(); + if (playlist == Playlist()) + playlist = Playlist::active_playlist(); + + playlist.prev_album(); +} + +static void add_list(Index<PlaylistAddItem> && items, int at, bool to_temp, + bool play) +{ + if (to_temp) + Playlist::temporary_playlist().activate(); + + Playlist::active_playlist().insert_items(at, std::move(items), play); +} + +EXPORT void aud_drct_pl_add(const char * filename, int at) +{ + Index<PlaylistAddItem> items; + items.append(String(filename)); + add_list(std::move(items), at, false, false); +} + +EXPORT void aud_drct_pl_add_list(Index<PlaylistAddItem> && items, int at) +{ + add_list(std::move(items), at, false, false); +} + +EXPORT void aud_drct_pl_open(const char * filename) +{ + Index<PlaylistAddItem> items; + items.append(String(filename)); + add_list(std::move(items), -1, aud_get_bool("open_to_temporary"), true); +} + +EXPORT void aud_drct_pl_open_list(Index<PlaylistAddItem> && items) +{ + add_list(std::move(items), -1, aud_get_bool("open_to_temporary"), true); +} + +EXPORT void aud_drct_pl_open_temp(const char * filename) +{ + Index<PlaylistAddItem> items; + items.append(String(filename)); + add_list(std::move(items), -1, true, true); +} + +EXPORT void aud_drct_pl_open_temp_list(Index<PlaylistAddItem> && items) +{ + add_list(std::move(items), -1, true, true); +} diff --git a/src/libaudcore/drct.h b/src/libaudcore/drct.h new file mode 100644 index 0000000..086a244 --- /dev/null +++ b/src/libaudcore/drct.h @@ -0,0 +1,111 @@ +/* + * drct.h + * Copyright 2010-2012 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_DRCT_H +#define LIBAUDCORE_DRCT_H + +#include <libaudcore/audio.h> +#include <libaudcore/index.h> +#include <libaudcore/tuple.h> + +class PluginHandle; + +/* CAUTION: These functions are not thread safe. */ + +/* --- PLAYBACK CONTROL --- */ + +void aud_drct_play(); +void aud_drct_play_pause(); +void aud_drct_pause(); +void aud_drct_stop(); +bool aud_drct_get_playing(); +bool aud_drct_get_ready(); +bool aud_drct_get_paused(); + +// returns entry number of playing song (zero-based) +int aud_drct_get_position(); + +// returns filename of playing song +String aud_drct_get_filename(); + +// returns formatted title of playing song +// connect to the "title change" hook to be notified of changes +String aud_drct_get_title(); + +// returns metadata of playing song +// connect to the "tuple change" hook to be notified of changes +Tuple aud_drct_get_tuple(); + +// returns some statistics of playing song +// connect to the "info change" hook to be notified of changes +void aud_drct_get_info(int & bitrate, int & samplerate, int & channels); + +int aud_drct_get_time(); +int aud_drct_get_length(); +void aud_drct_seek(int time); + +/* "A-B repeat": when playback reaches point B, it returns to point A (where A + * and B are in milliseconds). The value -1 is interpreted as the beginning of + * the song (for A) or the end of the song (for B). A-B repeat is disabled + * entirely by setting both A and B to -1. */ +void aud_drct_set_ab_repeat(int a, int b); +void aud_drct_get_ab_repeat(int & a, int & b); + +/* --- RECORDING CONTROL --- */ + +/* Note that the behavior of these functions has changed in Audacious 3.9; + * "enabled" now means only that a plugin has been selected for recording. + * The "record" config option is now used to start/stop recording. */ + +/* Returns the output plugin that will be used for recording, or null if none is + * available. Connect to the "enable record" hook to monitor changes. */ +PluginHandle * aud_drct_get_record_plugin(); + +/* Returns true if output recording is enabled, otherwise false. Connect to the + * "enable record" hook to monitor changes. */ +bool aud_drct_get_record_enabled(); + +/* Enables or disables output recording (but does not actually start recording). + * Returns true on success, otherwise false. */ +bool aud_drct_enable_record(bool enable); + +/* --- VOLUME CONTROL --- */ + +StereoVolume aud_drct_get_volume(); +void aud_drct_set_volume(StereoVolume volume); +int aud_drct_get_volume_main(); +void aud_drct_set_volume_main(int volume); +int aud_drct_get_volume_balance(); +void aud_drct_set_volume_balance(int balance); + +/* --- PLAYLIST CONTROL --- */ + +void aud_drct_pl_next(); +void aud_drct_pl_next_album(); +void aud_drct_pl_prev(); +void aud_drct_pl_prev_album(); + +void aud_drct_pl_add(const char * filename, int at); +void aud_drct_pl_add_list(Index<PlaylistAddItem> && items, int at); +void aud_drct_pl_open(const char * filename); +void aud_drct_pl_open_list(Index<PlaylistAddItem> && items); +void aud_drct_pl_open_temp(const char * filename); +void aud_drct_pl_open_temp_list(Index<PlaylistAddItem> && items); + +#endif diff --git a/src/libaudcore/effect.cc b/src/libaudcore/effect.cc new file mode 100644 index 0000000..cd348b6 --- /dev/null +++ b/src/libaudcore/effect.cc @@ -0,0 +1,261 @@ +/* + * effect.c + * Copyright 2010-2012 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "internal.h" + +#include "drct.h" +#include "list.h" +#include "plugin.h" +#include "plugins.h" +#include "runtime.h" +#include "threads.h" + +struct Effect : public ListNode +{ + PluginHandle * plugin; + int position; + EffectPlugin * header; + int channels_returned, rate_returned; + bool remove_flag; +}; + +static aud::mutex mutex; +static List<Effect> effects; +static int input_channels, input_rate; + +void effect_start(int & channels, int & rate) +{ + auto mh = mutex.take(); + + AUDDBG("Starting effects.\n"); + + effects.clear(); + + input_channels = channels; + input_rate = rate; + + auto & list = aud_plugin_list(PluginType::Effect); + + for (int i = 0; i < list.len(); i++) + { + PluginHandle * plugin = list[i]; + if (!aud_plugin_get_enabled(plugin)) + continue; + + AUDINFO("Starting %s at %d channels, %d Hz.\n", + aud_plugin_get_name(plugin), channels, rate); + + EffectPlugin * header = (EffectPlugin *)aud_plugin_get_header(plugin); + if (!header) + continue; + + header->start(channels, rate); + + Effect * effect = new Effect(); + effect->plugin = plugin; + effect->position = i; + effect->header = header; + effect->channels_returned = channels; + effect->rate_returned = rate; + + effects.append(effect); + } +} + +Index<float> & effect_process(Index<float> & data) +{ + auto mh = mutex.take(); + Index<float> * cur = &data; + + Effect * e = effects.head(); + while (e) + { + Effect * next = effects.next(e); + + if (e->remove_flag) + { + cur = &e->header->finish(*cur, false); + + // simulate end-of-playlist call + // first save the current data + Index<float> save = std::move(*cur); + cur = &e->header->finish(*cur, true); + + // combine the saved and new data + save.move_from(*cur, 0, -1, -1, true, true); + *cur = std::move(save); + + effects.remove(e); + delete e; + } + else + cur = &e->header->process(*cur); + + e = next; + } + + return *cur; +} + +bool effect_flush(bool force) +{ + auto mh = mutex.take(); + bool flushed = true; + + for (Effect * e = effects.head(); e; e = effects.next(e)) + { + if (!e->header->flush(force) && !force) + { + flushed = false; + break; + } + } + + return flushed; +} + +Index<float> & effect_finish(Index<float> & data, bool end_of_playlist) +{ + auto mh = mutex.take(); + Index<float> * cur = &data; + + for (Effect * e = effects.head(); e; e = effects.next(e)) + cur = &e->header->finish(*cur, end_of_playlist); + + return *cur; +} + +int effect_adjust_delay(int delay) +{ + auto mh = mutex.take(); + + for (Effect * e = effects.tail(); e; e = effects.prev(e)) + delay = e->header->adjust_delay(delay); + + return delay; +} + +static void effect_insert(aud::mutex::holder &, PluginHandle * plugin, + EffectPlugin * header) +{ + int position = aud_plugin_list(PluginType::Effect).find(plugin); + + Effect * prev = nullptr; + + for (Effect * e = effects.head(); e; e = effects.next(e)) + { + if (e->plugin == plugin) + { + e->remove_flag = false; + return; + } + + if (e->position > position) + break; + + prev = e; + } + + AUDDBG("Adding %s without reset.\n", aud_plugin_get_name(plugin)); + + int channels, rate; + if (prev) + { + AUDDBG("Adding %s after %s.\n", aud_plugin_get_name(plugin), + aud_plugin_get_name(prev->plugin)); + channels = prev->channels_returned; + rate = prev->rate_returned; + } + else + { + AUDDBG("Adding %s as first effect.\n", aud_plugin_get_name(plugin)); + channels = input_channels; + rate = input_rate; + } + + AUDINFO("Starting %s at %d channels, %d Hz.\n", aud_plugin_get_name(plugin), + channels, rate); + header->start(channels, rate); + + Effect * effect = new Effect(); + effect->plugin = plugin; + effect->position = position; + effect->header = header; + effect->channels_returned = channels; + effect->rate_returned = rate; + + effects.insert_after(prev, effect); +} + +static void effect_remove(aud::mutex::holder &, PluginHandle * plugin) +{ + for (Effect * e = effects.head(); e; e = effects.next(e)) + { + if (e->plugin == plugin) + { + AUDDBG("Removing %s without reset.\n", aud_plugin_get_name(plugin)); + e->remove_flag = true; + return; + } + } +} + +static void effect_enable(PluginHandle * plugin, EffectPlugin * ep, bool enable) +{ + if (ep->preserves_format) + { + auto mh = mutex.take(); + + if (enable) + effect_insert(mh, plugin, ep); + else + effect_remove(mh, plugin); + } + else + { + AUDDBG("Reset to add/remove %s.\n", aud_plugin_get_name(plugin)); + aud_output_reset(OutputReset::EffectsOnly); + } +} + +bool effect_plugin_start(PluginHandle * plugin) +{ + if (aud_drct_get_playing()) + { + EffectPlugin * ep = (EffectPlugin *)aud_plugin_get_header(plugin); + if (!ep) + return false; + + effect_enable(plugin, ep, true); + } + + return true; +} + +void effect_plugin_stop(PluginHandle * plugin) +{ + if (aud_drct_get_playing()) + { + EffectPlugin * ep = (EffectPlugin *)aud_plugin_get_header(plugin); + if (!ep) + return; + + effect_enable(plugin, ep, false); + } +} diff --git a/src/libaudcore/equalizer-preset.cc b/src/libaudcore/equalizer-preset.cc new file mode 100644 index 0000000..53e20e2 --- /dev/null +++ b/src/libaudcore/equalizer-preset.cc @@ -0,0 +1,233 @@ +/* + * equalizer_preset.c + * Copyright 2003-2013 Eugene Zagidullin, Ariadne Conill, John Lindgren, and + * Thomas Lange + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#define AUD_GLIB_INTEGRATION +#include "equalizer.h" + +#include <math.h> +#include <string.h> + +#include "audstrings.h" +#include "runtime.h" +#include "vfs.h" + +EXPORT Index<EqualizerPreset> aud_eq_read_presets(const char * basename) +{ + Index<EqualizerPreset> list; + + GKeyFile * rcfile = g_key_file_new(); + StringBuf filename = + filename_build({aud_get_path(AudPath::UserDir), basename}); + + if (!g_key_file_load_from_file(rcfile, filename, G_KEY_FILE_NONE, nullptr)) + { + StringBuf filename2 = + filename_build({aud_get_path(AudPath::DataDir), basename}); + + if (!g_key_file_load_from_file(rcfile, filename2, G_KEY_FILE_NONE, + nullptr)) + { + g_key_file_free(rcfile); + return list; + } + } + + for (int p = 0;; p++) + { + CharPtr name(g_key_file_get_string(rcfile, "Presets", + str_printf("Preset%d", p), nullptr)); + if (!name || !name[0]) + break; + + EqualizerPreset & preset = list.append(String(name)); + preset.preamp = g_key_file_get_double(rcfile, name, "Preamp", nullptr); + + for (int i = 0; i < AUD_EQ_NBANDS; i++) + preset.bands[i] = g_key_file_get_double( + rcfile, name, str_printf("Band%d", i), nullptr); + } + + g_key_file_free(rcfile); + + return list; +} + +EXPORT bool aud_eq_write_presets(const Index<EqualizerPreset> & list, + const char * basename) +{ + GKeyFile * rcfile = g_key_file_new(); + + for (int p = 0; p < list.len(); p++) + { + const EqualizerPreset & preset = list[p]; + + g_key_file_set_string(rcfile, "Presets", str_printf("Preset%d", p), + preset.name); + g_key_file_set_double(rcfile, preset.name, "Preamp", preset.preamp); + + for (int i = 0; i < AUD_EQ_NBANDS; i++) + g_key_file_set_double(rcfile, preset.name, str_printf("Band%d", i), + preset.bands[i]); + } + + size_t len; + CharPtr data(g_key_file_to_data(rcfile, &len, nullptr)); + + StringBuf filename = + filename_build({aud_get_path(AudPath::UserDir), basename}); + bool success = g_file_set_contents(filename, data, len, nullptr); + + g_key_file_free(rcfile); + + return success; +} + +/* Note: Winamp 2.x had a +/- 20 dB range. + * Winamp 5.x had a +/- 12 dB range, which we use here. */ + +/* Encoded values range from 0 (+12 dB) to 63 (-12 dB). The sign is + * reversed for some unknown reason. Mathematically, there is no way + * to represent 0 dB exactly (31 is +0.19 dB, 32 is -0.19 dB) but we + * mimic WinAmp in letting 31 mean 0 dB as a special case. */ + +static float decode_winamp_val(int val) +{ + if (val == 31) + return 0.0f; + + return (31.5f - val) * (12.0f / 31.5f); +} + +static int encode_winamp_val(float val) +{ + if (val == 0.0f) + return 31; + + return lroundf(31.5f - val * (31.5f / 12.0f)); +} + +EXPORT Index<EqualizerPreset> aud_import_winamp_presets(VFSFile & file) +{ + char header[31]; + char bands[11]; + char preset_name[181]; + + Index<EqualizerPreset> list; + + if (file.fread(header, 1, sizeof header) != sizeof header || + strncmp(header, "Winamp EQ library file v1.1", 27)) + return list; + + while (file.fread(preset_name, 1, 180) == 180 && preset_name[0]) + { + preset_name[180] = 0; /* protect against buffer overflow */ + + if (file.fseek(77, VFS_SEEK_CUR)) /* unknown crap --asphyx */ + break; + + if (file.fread(bands, 1, 11) != 11) + break; + + EqualizerPreset & preset = list.append(String(preset_name)); + preset.preamp = decode_winamp_val(bands[10]); + + for (int i = 0; i < AUD_EQ_NBANDS; i++) + preset.bands[i] = decode_winamp_val(bands[i]); + } + + return list; +} + +EXPORT bool aud_export_winamp_preset(const EqualizerPreset & preset, + VFSFile & file) +{ + char name[257]; + char bands[11]; + + if (file.fwrite("Winamp EQ library file v1.1\x1a!--", 1, 31) != 31) + return false; + + strncpy(name, preset.name, 257); + + if (file.fwrite(name, 1, 257) != 257) + return false; + + for (int i = 0; i < AUD_EQ_NBANDS; i++) + bands[i] = encode_winamp_val(preset.bands[i]); + + bands[10] = encode_winamp_val(preset.preamp); + + if (file.fwrite(bands, 1, 11) != 11) + return false; + + return true; +} + +EXPORT bool aud_save_preset_file(const EqualizerPreset & preset, VFSFile & file) +{ + GKeyFile * rcfile = g_key_file_new(); + + g_key_file_set_double(rcfile, "Equalizer preset", "Preamp", preset.preamp); + + for (int i = 0; i < AUD_EQ_NBANDS; i++) + g_key_file_set_double(rcfile, "Equalizer preset", + str_printf("Band%d", i), preset.bands[i]); + + size_t len; + CharPtr data(g_key_file_to_data(rcfile, &len, nullptr)); + + bool success = (file.fwrite(data, 1, len) == (int64_t)len); + + g_key_file_free(rcfile); + + return success; +} + +EXPORT bool aud_load_preset_file(EqualizerPreset & preset, VFSFile & file) +{ + /* get the preset name from the file name */ + StringBuf name = uri_get_display_base(file.filename()); + if (!name || !name[0]) + return false; + + GKeyFile * rcfile = g_key_file_new(); + + Index<char> data = file.read_all(); + + if (!data.len() || + !g_key_file_load_from_data(rcfile, data.begin(), data.len(), + G_KEY_FILE_NONE, nullptr)) + { + g_key_file_free(rcfile); + return false; + } + + preset.name = String(name); + preset.preamp = + g_key_file_get_double(rcfile, "Equalizer preset", "Preamp", nullptr); + + for (int i = 0; i < AUD_EQ_NBANDS; i++) + preset.bands[i] = g_key_file_get_double( + rcfile, "Equalizer preset", str_printf("Band%d", i), nullptr); + + g_key_file_free(rcfile); + + return true; +} diff --git a/src/libaudcore/equalizer.cc b/src/libaudcore/equalizer.cc new file mode 100644 index 0000000..7cc6aa8 --- /dev/null +++ b/src/libaudcore/equalizer.cc @@ -0,0 +1,227 @@ +/* + * equalizer.c + * Copyright 2001 Anders Johansson + * Copyright 2010-2015 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +/* + * Anders Johansson prefers float *ptr; formatting. Please keep it that way. + * - tallica + */ + +#include "equalizer.h" +#include "internal.h" + +#include <assert.h> +#include <math.h> +#include <string.h> + +#include "audio.h" +#include "audstrings.h" +#include "hook.h" +#include "runtime.h" +#include "threads.h" + +/* Q value for band-pass filters 1.2247 = (3/2)^(1/2) + * Gives 4 dB suppression at Fc*2 and Fc/2 */ +#define Q 1.2247449f + +/* Center frequencies for band-pass filters (Hz) */ +/* These are not the historical WinAmp frequencies, because the IIR filters used + * here are designed for each frequency to be twice the previous. Using WinAmp + * frequencies leads to too much gain in some bands and too little in others. */ +static const float CF[AUD_EQ_NBANDS] = {31.25f, 62.5f, 125, 250, 500, + 1000, 2000, 4000, 8000, 16000}; + +static aud::mutex mutex; +static bool active; +static int channels, rate; +static float a[AUD_EQ_NBANDS][2]; /* A weights */ +static float b[AUD_EQ_NBANDS][2]; /* B weights */ +static float wqv[AUD_MAX_CHANNELS][AUD_EQ_NBANDS] + [2]; /* Circular buffer for W data */ +static float gv[AUD_MAX_CHANNELS] + [AUD_EQ_NBANDS]; /* Gain factor for each channel and band */ +static int K; /* Number of used EQ bands */ + +/* 2nd order band-pass filter design */ +static void bp2(float * a, float * b, float fc) +{ + float th = 2 * (float)M_PI * fc; + float C = (1 - tanf(th * Q / 2)) / (1 + tanf(th * Q / 2)); + + a[0] = (1 + C) * cosf(th); + a[1] = -C; + b[0] = (1 - C) / 2; + b[1] = -1.005f; +} + +void eq_set_format(int new_channels, int new_rate) +{ + auto mh = mutex.take(); + + channels = new_channels; + rate = new_rate; + + /* Calculate number of active filters: the center frequency must be less + * than rate/2Q to avoid singularities in the tangent used in bp2() */ + K = AUD_EQ_NBANDS; + + while (K > 0 && CF[K - 1] > (float)rate / (2.005f * Q)) + K--; + + /* Generate filter taps */ + for (int k = 0; k < K; k++) + bp2(a[k], b[k], CF[k] / (float)rate); + + /* Reset state */ + memset(wqv[0][0], 0, sizeof wqv); +} + +static void eq_set_bands_real(aud::mutex::holder &, double preamp, + double * values) +{ + float adj[AUD_EQ_NBANDS]; + + for (int i = 0; i < AUD_EQ_NBANDS; i++) + adj[i] = preamp + values[i]; + + for (int c = 0; c < AUD_MAX_CHANNELS; c++) + { + for (int i = 0; i < AUD_EQ_NBANDS; i++) + gv[c][i] = powf(10, adj[i] / 20) - 1; + } +} + +void eq_filter(float * data, int samples) +{ + auto mh = mutex.take(); + + if (!active) + return; + + for (int channel = 0; channel < channels; channel++) + { + float * g = gv[channel]; /* Gain factor */ + float * end = data + samples; + + for (float * f = data + channel; f < end; f += channels) + { + float yt = *f; /* Current input sample */ + + for (int k = 0; k < K; k++) + { + /* Pointer to circular buffer wq */ + float * wq = wqv[channel][k]; + /* Calculate output from AR part of current filter */ + float w = yt * b[k][0] + wq[0] * a[k][0] + wq[1] * a[k][1]; + + /* Calculate output from MA part of current filter */ + yt += (w + wq[1] * b[k][1]) * g[k]; + + /* Update circular buffer */ + wq[1] = wq[0]; + wq[0] = w; + } + + /* Calculate output */ + *f = yt; + } + } +} + +static void eq_update(void *, void *) +{ + auto mh = mutex.take(); + + active = aud_get_bool("equalizer_active"); + + double values[AUD_EQ_NBANDS]; + aud_eq_get_bands(values); + eq_set_bands_real(mh, aud_get_double("equalizer_preamp"), values); +} + +void eq_init() +{ + eq_update(nullptr, nullptr); + hook_associate("set equalizer_active", eq_update, nullptr); + hook_associate("set equalizer_preamp", eq_update, nullptr); + hook_associate("set equalizer_bands", eq_update, nullptr); +} + +void eq_cleanup() +{ + hook_dissociate("set equalizer_active", eq_update); + hook_dissociate("set equalizer_preamp", eq_update); + hook_dissociate("set equalizer_bands", eq_update); +} + +EXPORT void aud_eq_set_bands(const double values[AUD_EQ_NBANDS]) +{ + StringBuf string = double_array_to_str(values, AUD_EQ_NBANDS); + aud_set_str("equalizer_bands", string); +} + +EXPORT void aud_eq_get_bands(double values[AUD_EQ_NBANDS]) +{ + memset(values, 0, sizeof(double) * AUD_EQ_NBANDS); + String string = aud_get_str("equalizer_bands"); + str_to_double_array(string, values, AUD_EQ_NBANDS); +} + +EXPORT void aud_eq_set_band(int band, double value) +{ + assert(band >= 0 && band < AUD_EQ_NBANDS); + + double values[AUD_EQ_NBANDS]; + aud_eq_get_bands(values); + values[band] = value; + aud_eq_set_bands(values); +} + +EXPORT double aud_eq_get_band(int band) +{ + assert(band >= 0 && band < AUD_EQ_NBANDS); + + double values[AUD_EQ_NBANDS]; + aud_eq_get_bands(values); + return values[band]; +} + +EXPORT void aud_eq_apply_preset(const EqualizerPreset & preset) +{ + double bands[AUD_EQ_NBANDS]; + + /* convert float to double :( */ + for (int i = 0; i < AUD_EQ_NBANDS; i++) + bands[i] = preset.bands[i]; + + aud_eq_set_bands(bands); + aud_set_double("equalizer_preamp", preset.preamp); +} + +EXPORT void aud_eq_update_preset(EqualizerPreset & preset) +{ + double bands[AUD_EQ_NBANDS]; + aud_eq_get_bands(bands); + + /* convert double to float :( */ + for (int i = 0; i < AUD_EQ_NBANDS; i++) + preset.bands[i] = bands[i]; + + preset.preamp = aud_get_double("equalizer_preamp"); +} diff --git a/src/libaudcore/equalizer.h b/src/libaudcore/equalizer.h new file mode 100644 index 0000000..cf9441c --- /dev/null +++ b/src/libaudcore/equalizer.h @@ -0,0 +1,56 @@ +/* + * equalizer.h + * Copyright 2014-2015 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_EQUALIZER_H +#define LIBAUDCORE_EQUALIZER_H + +#include <libaudcore/index.h> +#include <libaudcore/objects.h> + +class VFSFile; + +#define AUD_EQ_NBANDS 10 +#define AUD_EQ_MAX_GAIN 12 + +struct EqualizerPreset +{ + String name; + float preamp; + float bands[AUD_EQ_NBANDS]; +}; + +void aud_eq_set_bands(const double values[AUD_EQ_NBANDS]); +void aud_eq_get_bands(double values[AUD_EQ_NBANDS]); +void aud_eq_set_band(int band, double value); +double aud_eq_get_band(int band); + +void aud_eq_apply_preset(const EqualizerPreset & preset); +void aud_eq_update_preset(EqualizerPreset & preset); + +Index<EqualizerPreset> aud_eq_read_presets(const char * basename); +bool aud_eq_write_presets(const Index<EqualizerPreset> & list, + const char * basename); + +bool aud_load_preset_file(EqualizerPreset & preset, VFSFile & file); +bool aud_save_preset_file(const EqualizerPreset & preset, VFSFile & file); + +Index<EqualizerPreset> aud_import_winamp_presets(VFSFile & file); +bool aud_export_winamp_preset(const EqualizerPreset & preset, VFSFile & file); + +#endif /* LIBAUDCORE_EQUALIZER_H */ diff --git a/src/libaudcore/eventqueue.cc b/src/libaudcore/eventqueue.cc new file mode 100644 index 0000000..767cf1a --- /dev/null +++ b/src/libaudcore/eventqueue.cc @@ -0,0 +1,125 @@ +/* + * eventqueue.cc + * Copyright 2011-2014 John Lindgren, Michał Lipski + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "hook.h" + +#include <string.h> + +#include "internal.h" +#include "list.h" +#include "mainloop.h" +#include "objects.h" +#include "threads.h" + +struct Event : public ListNode +{ + String name; + void * data; + void (*destroy)(void *); + + Event(const char * name, void * data, EventDestroyFunc destroy) + : name(name), data(data), destroy(destroy) + { + } + + ~Event() + { + if (destroy) + destroy(data); + } +}; + +static aud::mutex mutex; +static bool paused; +static List<Event> events; +static QueuedFunc queued_events; + +static void events_execute(void *) +{ + auto mh = mutex.take(); + + Event * event; + while (!paused && (event = events.head())) + { + events.remove(event); + + mh.unlock(); + + hook_call(event->name, event->data); + delete event; + + mh.lock(); + } +} + +EXPORT void event_queue(const char * name, void * data, + EventDestroyFunc destroy) +{ + auto mh = mutex.take(); + + if (!paused && !events.head()) + queued_events.queue(events_execute, nullptr); + + events.append(new Event(name, data, destroy)); +} + +EXPORT void event_queue_cancel(const char * name, void * data) +{ + auto mh = mutex.take(); + + Event * event = events.head(); + while (event) + { + Event * next = events.next(event); + + if (!strcmp(event->name, name) && (!data || event->data == data)) + { + events.remove(event); + delete event; + } + + event = next; + } +} + +// this is only for use by the playlist, to ensure that queued playlist +// updates are processed before generic events +void event_queue_pause() +{ + auto mh = mutex.take(); + if (!paused) + queued_events.stop(); + + paused = true; +} + +void event_queue_unpause() +{ + auto mh = mutex.take(); + if (paused && events.head()) + queued_events.queue(events_execute, nullptr); + + paused = false; +} + +void event_queue_cancel_all() +{ + auto mh = mutex.take(); + events.clear(); +} diff --git a/src/libaudcore/export.h b/src/libaudcore/export.h new file mode 100644 index 0000000..f34332b --- /dev/null +++ b/src/libaudcore/export.h @@ -0,0 +1,33 @@ +/* + * export.h + * Copyright 2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_EXPORT_H +#define LIBAUDCORE_EXPORT_H + +#ifdef _WIN32 +#ifdef LIBAUDCORE_BUILD +#define LIBAUDCORE_PUBLIC __declspec(dllexport) +#else +#define LIBAUDCORE_PUBLIC __declspec(dllimport) +#endif +#else +#define LIBAUDCORE_PUBLIC __attribute__((visibility("default"))) +#endif + +#endif // LIBAUDCORE_EXPORT_H diff --git a/src/libaudcore/fft.cc b/src/libaudcore/fft.cc new file mode 100644 index 0000000..0587e7b --- /dev/null +++ b/src/libaudcore/fft.cc @@ -0,0 +1,123 @@ +/* + * fft.c + * Copyright 2011 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "internal.h" + +#include <complex> +#include <math.h> + +#define TWO_PI 6.2831853f + +#define N 512 /* size of the DFT */ +#define LOGN 9 /* log N (base 2) */ + +typedef std::complex<float> Complex; + +static float hamming[N]; /* hamming window, scaled to sum to 1 */ +static int reversed[N]; /* bit-reversal table */ +static Complex roots[N / 2]; /* N-th roots of unity */ +static char generated = 0; /* set if tables have been generated */ + +/* Reverse the order of the lowest LOGN bits in an integer. */ + +static int bit_reverse(int x) +{ + int y = 0; + + for (int n = LOGN; n--;) + { + y = (y << 1) | (x & 1); + x >>= 1; + } + + return y; +} + +/* Generate lookup tables. */ + +static void generate_tables() +{ + if (generated) + return; + + for (int n = 0; n < N; n++) + hamming[n] = 1 - 0.85f * cosf(n * (TWO_PI / N)); + for (int n = 0; n < N; n++) + reversed[n] = bit_reverse(n); + for (int n = 0; n < N / 2; n++) + roots[n] = exp(Complex(0, n * (TWO_PI / N))); + + generated = 1; +} + +/* Perform the DFT using the Cooley-Tukey algorithm. At each step s, where + * s=1..log N (base 2), there are N/(2^s) groups of intertwined butterfly + * operations. Each group contains (2^s)/2 butterflies, and each butterfly has + * a span of (2^s)/2. The twiddle factors are nth roots of unity where n = 2^s. + */ + +static void do_fft(Complex a[N]) +{ + int half = 1; /* (2^s)/2 */ + int inv = N / 2; /* N/(2^s) */ + + /* loop through steps */ + while (inv) + { + /* loop through groups */ + for (int g = 0; g < N; g += half << 1) + { + /* loop through butterflies */ + for (int b = 0, r = 0; b < half; b++, r += inv) + { + Complex even = a[g + b]; + Complex odd = roots[r] * a[g + half + b]; + a[g + b] = even + odd; + a[g + half + b] = even - odd; + } + } + + half <<= 1; + inv >>= 1; + } +} + +/* Input is N=512 PCM samples. + * Output is intensity of frequencies from 1 to N/2=256. */ + +void calc_freq(const float data[N], float freq[N / 2]) +{ + generate_tables(); + + /* input is filtered by a Hamming window */ + /* input values are in bit-reversed order */ + Complex a[N]; + for (int n = 0; n < N; n++) + a[reversed[n]] = data[n] * hamming[n]; + + do_fft(a); + + /* output values are divided by N */ + /* frequencies from 1 to N/2-1 are doubled */ + for (int n = 0; n < N / 2 - 1; n++) + freq[n] = 2 * abs(a[1 + n]) / N; + + /* frequency N/2 is not doubled */ + freq[N / 2 - 1] = abs(a[N / 2]) / N; +} diff --git a/src/libaudcore/history.cc b/src/libaudcore/history.cc new file mode 100644 index 0000000..0f3c2b4 --- /dev/null +++ b/src/libaudcore/history.cc @@ -0,0 +1,58 @@ +/* + * history.c + * Copyright 2011 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "audstrings.h" +#include "runtime.h" + +#include <string.h> + +#define MAX_ENTRIES 30 + +EXPORT String aud_history_get(int entry) +{ + StringBuf name = str_printf("entry%d", entry); + String path = aud_get_str("history", name); + return (path[0] ? path : String()); +} + +EXPORT void aud_history_add(const char * path) +{ + String add = String(path); + + for (int i = 0; i < MAX_ENTRIES; i++) + { + StringBuf name = str_printf("entry%d", i); + String old = aud_get_str("history", name); + aud_set_str("history", name, add); + + if (!strcmp(old, path)) + break; + + add = old; + } +} + +EXPORT void aud_history_clear() +{ + for (int i = 0; i < MAX_ENTRIES; i++) + { + StringBuf name = str_printf("entry%d", i); + aud_set_str("history", name, ""); + } +} diff --git a/src/libaudcore/hook.cc b/src/libaudcore/hook.cc new file mode 100644 index 0000000..0364ced --- /dev/null +++ b/src/libaudcore/hook.cc @@ -0,0 +1,131 @@ +/* + * hook.c + * Copyright 2011-2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "hook.h" + +#include "index.h" +#include "internal.h" +#include "multihash.h" +#include "objects.h" +#include "runtime.h" +#include "threads.h" + +struct HookItem +{ + HookFunction func; + void * user; +}; + +struct HookList +{ + Index<HookItem> items; + int use_count; + + void compact() + { + auto is_empty = [](const HookItem & item) { return !item.func; }; + + items.remove_if(is_empty); + } +}; + +static aud::mutex mutex; +static SimpleHash<String, HookList> hooks; + +EXPORT void hook_associate(const char * name, HookFunction func, void * user) +{ + auto mh = mutex.take(); + + String key(name); + HookList * list = hooks.lookup(key); + if (!list) + list = hooks.add(key, HookList()); + + list->items.append(func, user); +} + +EXPORT void hook_dissociate(const char * name, HookFunction func, void * user) +{ + auto mh = mutex.take(); + + String key(name); + HookList * list = hooks.lookup(key); + if (!list) + return; + + for (HookItem & item : list->items) + { + if (item.func == func && (!user || item.user == user)) + item.func = nullptr; + } + + if (!list->use_count) + { + list->compact(); + if (!list->items.len()) + hooks.remove(key); + } +} + +EXPORT void hook_call(const char * name, void * data) +{ + auto mh = mutex.take(); + + String key(name); + HookList * list = hooks.lookup(key); + if (!list) + return; + + list->use_count++; + + /* note: the list may grow (but not shrink) during the hook call */ + for (int i = 0; i < list->items.len(); i++) + { + /* copy locally to prevent race condition */ + HookItem item = list->items[i]; + + if (item.func) + { + mh.unlock(); + item.func(data, item.user); + mh.lock(); + } + } + + list->use_count--; + + if (!list->use_count) + { + list->compact(); + if (!list->items.len()) + hooks.remove(key); + } +} + +void hook_cleanup() +{ + auto mh = mutex.take(); + + hooks.iterate([](const String & name, HookList & list) { + AUDWARN("Hook not disconnected: %s (%d)\n", (const char *)name, + list.items.len()); + }); + + hooks.clear(); +} diff --git a/src/libaudcore/hook.h b/src/libaudcore/hook.h new file mode 100644 index 0000000..176076d --- /dev/null +++ b/src/libaudcore/hook.h @@ -0,0 +1,174 @@ +/* + * hook.h + * Copyright 2011-2015 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_HOOK_H +#define LIBAUDCORE_HOOK_H + +#include <libaudcore/templates.h> + +// Timer API. This API allows functions to be registered to run at a given +// periodic rate. The advantage of this API rather than QueuedFunc (see +// mainloop.h) is that multiple functions can run on the same timer tick, +// reducing CPU wakeups. +// ======================================================================== + +enum class TimerRate +{ + Hz1, + Hz4, + Hz10, + Hz30, + count +}; + +typedef void (*TimerFunc)(void * data); + +/* Adds <func> to the list of functions to be called at the given <rate>, + * unless it has already been added with the same <data>. */ +void timer_add(TimerRate rate, TimerFunc func, void * data = nullptr); + +/* Removes all instances matching <func> and <data> from the list of functions + * to be called at the given <rate>. If <data> is nullptr, all instances + * matching <func> are removed. */ +void timer_remove(TimerRate rate, TimerFunc func, void * data = nullptr); + +/* Convenience wrapper for C++ classes. Allows non-static member functions to + * be used as timer callbacks. The Timer should be made a member of the class + * in question so that timer_remove() is called automatically from the + * destructor. Note that the timer is not started automatically. */ +template<class T> +class Timer +{ +public: + Timer(TimerRate rate, T * target, void (T::*func)()) + : rate(rate), target(target), func(func) + { + } + + void start() const { timer_add(rate, run, (void *)this); } + void stop() const { timer_remove(rate, run, (void *)this); } + + ~Timer() { stop(); } + + Timer(const Timer &) = delete; + void operator=(const Timer &) = delete; + +private: + const TimerRate rate; + T * const target; + void (T::*const func)(); + + static void run(void * timer_) + { + auto timer = (const Timer *)timer_; + (timer->target->*timer->func)(); + } +}; + +// Hook API. This API allows functions to be registered to run when a given +// named event, or "hook", is called. +// ========================================================================= + +typedef void (*HookFunction)(void * data, void * user); + +/* Adds <func> to the list of functions to be called when the hook <name> is + * triggered. */ +void hook_associate(const char * name, HookFunction func, void * user); + +/* Removes all instances matching <func> and <user> from the list of functions + * to be called when the hook <name> is triggered. If <user> is nullptr, all + * instances matching <func> are removed. */ +void hook_dissociate(const char * name, HookFunction func, + void * user = nullptr); + +/* Triggers the hook <name>. */ +void hook_call(const char * name, void * data); + +typedef void (*EventDestroyFunc)(void * data); + +/* Schedules a call of the hook <name> from the program's main loop. + * If <destroy> is not nullptr, it will be called on <data> after the + * hook is called. */ +void event_queue(const char * name, void * data, + EventDestroyFunc destroy = nullptr); + +/* Cancels pending hook calls matching <name> and <data>. If <data> is nullptr, + * all hook calls matching <name> are canceled. */ +void event_queue_cancel(const char * name, void * data = nullptr); + +/* Convenience wrapper for C++ classes. Allows non-static member functions to + * be used as hook callbacks. The HookReceiver should be made a member of the + * class in question so that hook_dissociate() is called automatically from the + * destructor. */ +template<class T, class D = void> +class HookReceiver +{ +public: + HookReceiver(const char * hook, T * target, void (T::*func)(D)) + : hook(hook), target(target), func(func) + { + hook_associate(hook, run, this); + } + + ~HookReceiver() { hook_dissociate(hook, run, this); } + + HookReceiver(const HookReceiver &) = delete; + void operator=(const HookReceiver &) = delete; + +private: + const char * const hook; + T * const target; + void (T::*const func)(D); + + static void run(void * d, void * recv_) + { + auto recv = (const HookReceiver *)recv_; + (recv->target->*recv->func)(aud::from_ptr<D>(d)); + } +}; + +/* Partial specialization for data-less hooks. */ +template<class T> +class HookReceiver<T, void> +{ +public: + HookReceiver(const char * hook, T * target, void (T::*func)()) + : hook(hook), target(target), func(func) + { + hook_associate(hook, run, this); + } + + ~HookReceiver() { hook_dissociate(hook, run, this); } + + HookReceiver(const HookReceiver &) = delete; + void operator=(const HookReceiver &) = delete; + +private: + const char * const hook; + T * const target; + void (T::*const func)(); + + static void run(void *, void * recv_) + { + auto recv = (const HookReceiver *)recv_; + (recv->target->*recv->func)(); + } +}; + +#endif /* LIBAUDCORE_HOOK_H */ diff --git a/src/libaudcore/i18n.h b/src/libaudcore/i18n.h new file mode 100644 index 0000000..bbb48d7 --- /dev/null +++ b/src/libaudcore/i18n.h @@ -0,0 +1,45 @@ +/* + * i18n.h + * Copyright 2007 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef AUDACIOUS_I18N_H +#define AUDACIOUS_I18N_H + +#ifdef HAVE_GETTEXT + +#include <libintl.h> + +#define _(String) dgettext(PACKAGE, String) + +#ifdef gettext_noop +#define N_(String) gettext_noop(String) +#else +#define N_(String) (String) +#endif + +#else + +#define _(String) (String) +#define N_(String) (String) +#define dgettext(package, str) (str) +#define dngettext(package, str1, str2, count) (count > 1 ? str2 : str1) +#define ngettext(str1, str2, count) (count > 1 ? str2 : str1) + +#endif + +#endif /* AUDACIOUS_I18N_H */ diff --git a/src/libaudcore/index.cc b/src/libaudcore/index.cc new file mode 100644 index 0000000..d33a0e0 --- /dev/null +++ b/src/libaudcore/index.cc @@ -0,0 +1,254 @@ +/* + * index.cc + * Copyright 2014-2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "index.h" +#include "internal.h" + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include <glib.h> /* for g_qsort_with_data */ + +static void do_fill(void * data, int len, aud::FillFunc fill_func) +{ + if (fill_func) + fill_func(data, len); + else + memset(data, 0, len); +} + +static void do_erase(void * data, int len, aud::EraseFunc erase_func) +{ + if (erase_func) + erase_func(data, len); +} + +EXPORT void IndexBase::clear(aud::EraseFunc erase_func) +{ + if (!m_data) + return; + + __sync_sub_and_fetch(&misc_bytes_allocated, m_size); + + do_erase(m_data, m_len, erase_func); + free(m_data); + + m_data = nullptr; + m_len = 0; + m_size = 0; +} + +EXPORT void * IndexBase::insert(int pos, int len) +{ + assert(pos <= m_len); + assert(len >= 0); + + if (!len) + goto out; + + if (pos < 0) + pos = m_len; /* insert at end */ + + if (m_size < m_len + len) + { + /* never allocate less than 16 bytes */ + int new_size = aud::max(m_size, 16); + + /* next try 4/3 current size, biased toward multiples of 4 */ + if (new_size < m_len + len) + new_size = (new_size + 2) / 3 * 4; + + /* use requested size if still too small */ + if (new_size < m_len + len) + new_size = m_len + len; + + void * new_data = realloc(m_data, new_size); + if (!new_data) + throw std::bad_alloc(); /* nothing changed yet */ + + __sync_add_and_fetch(&misc_bytes_allocated, new_size - m_size); + + m_data = new_data; + m_size = new_size; + } + + memmove((char *)m_data + pos + len, (char *)m_data + pos, m_len - pos); + m_len += len; + +out: + return (char *)m_data + pos; +} + +EXPORT void IndexBase::insert(int pos, int len, aud::FillFunc fill_func) +{ + void * to = insert(pos, len); + + if (!len) + return; + + if (fill_func) + fill_func(to, len); + else + memset(to, 0, len); +} + +EXPORT void IndexBase::insert(const void * from, int pos, int len, + aud::CopyFunc copy_func) +{ + void * to = insert(pos, len); + + if (!len) + return; + + if (copy_func) + copy_func(from, to, len); + else + memcpy(to, from, len); +} + +EXPORT void IndexBase::remove(int pos, int len, aud::EraseFunc erase_func) +{ + assert(pos >= 0 && pos <= m_len); + assert(len <= m_len - pos); + + if (len < 0) + len = m_len - pos; /* remove all following */ + + if (!len) + return; + + do_erase((char *)m_data + pos, len, erase_func); + memmove((char *)m_data + pos, (char *)m_data + pos + len, + m_len - pos - len); + m_len -= len; +} + +EXPORT void IndexBase::erase(int pos, int len, aud::FillFunc fill_func, + aud::EraseFunc erase_func) +{ + assert(pos >= 0 && pos <= m_len); + assert(len <= m_len - pos); + + if (len < 0) + len = m_len - pos; /* erase all following */ + + if (!len) + return; + + do_erase((char *)m_data + pos, len, erase_func); + do_fill((char *)m_data + pos, len, fill_func); +} + +EXPORT void IndexBase::shift(int from, int to, int len, aud::FillFunc fill_func, + aud::EraseFunc erase_func) +{ + assert(len >= 0 && len <= m_len); + assert(from >= 0 && from + len <= m_len); + assert(to >= 0 && to + len <= m_len); + + if (!len) + return; + + int erase_len = aud::min(len, abs(to - from)); + + if (to < from) + do_erase((char *)m_data + to, erase_len, erase_func); + else + do_erase((char *)m_data + to + len - erase_len, erase_len, erase_func); + + memmove((char *)m_data + to, (char *)m_data + from, len); + + if (to < from) + do_fill((char *)m_data + from + len - erase_len, erase_len, fill_func); + else + do_fill((char *)m_data + from, erase_len, fill_func); +} + +EXPORT void IndexBase::move_from(IndexBase & b, int from, int to, int len, + bool expand, bool collapse, + aud::FillFunc fill_func, + aud::EraseFunc erase_func) +{ + assert(this != &b); + assert(from >= 0 && from <= b.m_len); + assert(len <= b.m_len - from); + + if (len < 0) + len = b.m_len - from; /* copy all following */ + + if (!len) + return; + + if (expand) + { + assert(to <= m_len); + if (to < 0) + to = m_len; /* insert at end */ + + insert(to, len); + } + else + { + assert(to >= 0 && to <= m_len - len); + do_erase((char *)m_data + to, len, erase_func); + } + + memcpy((char *)m_data + to, (char *)b.m_data + from, len); + + if (collapse) + { + memmove((char *)b.m_data + from, (char *)b.m_data + from + len, + b.m_len - from - len); + b.m_len -= len; + } + else + do_fill((char *)b.m_data + from, len, fill_func); +} + +EXPORT void IndexBase::sort(CompareFunc compare, int elemsize, void * userdata) +{ + if (!m_len) + return; + + // since we require GLib >= 2.32, g_qsort_with_data performs a stable sort + g_qsort_with_data(m_data, m_len / elemsize, elemsize, compare, userdata); +} + +EXPORT int IndexBase::bsearch(const void * key, CompareFunc compare, + int elemsize, void * userdata) const +{ + int top = 0; + int bottom = m_len / elemsize; + + while (top < bottom) + { + int middle = top + (bottom - top) / 2; + int match = compare(key, (char *)m_data + middle * elemsize, userdata); + + if (match < 0) + bottom = middle; + else if (match > 0) + top = middle + 1; + else + return middle; + } + + return -1; +} diff --git a/src/libaudcore/index.h b/src/libaudcore/index.h new file mode 100644 index 0000000..efc4ea7 --- /dev/null +++ b/src/libaudcore/index.h @@ -0,0 +1,222 @@ +/* + * index.h + * Copyright 2014-2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_INDEX_H +#define LIBAUDCORE_INDEX_H + +#include <libaudcore/templates.h> + +/* + * Index is a lightweight list class similar to std::vector, but with the + * following differences: + * - The base implementation is type-agnostic, so it only needs to be compiled + * once. Type-safety is provided by a thin template subclass. + * - Objects are moved in memory without calling any assignment operator. + * Be careful to use only objects that can handle this. + */ + +class IndexBase +{ +public: + typedef int (*CompareFunc)(const void * a, const void * b, void * userdata); + + constexpr IndexBase() : m_data(nullptr), m_len(0), m_size(0) {} + + void clear(aud::EraseFunc erase_func); // use as destructor + + IndexBase(IndexBase && b) + : m_data(b.m_data), m_len(b.m_len), m_size(b.m_size) + { + b.m_data = nullptr; + b.m_len = 0; + b.m_size = 0; + } + + void * begin() { return m_data; } + const void * begin() const { return m_data; } + void * end() { return (char *)m_data + m_len; } + const void * end() const { return (char *)m_data + m_len; } + + int len() const { return m_len; } + + void * insert(int pos, int len); // no fill + void insert(int pos, int len, aud::FillFunc fill_func); + void insert(const void * from, int pos, int len, aud::CopyFunc copy_func); + void remove(int pos, int len, aud::EraseFunc erase_func); + void erase(int pos, int len, aud::FillFunc fill_func, + aud::EraseFunc erase_func); + void shift(int from, int to, int len, aud::FillFunc fill_func, + aud::EraseFunc erase_func); + + void move_from(IndexBase & b, int from, int to, int len, bool expand, + bool collapse, aud::FillFunc fill_func, + aud::EraseFunc erase_func); + + void sort(CompareFunc compare, int elemsize, void * userdata); + int bsearch(const void * key, CompareFunc search, int elemsize, + void * userdata) const; + +private: + void * m_data; + int m_len, m_size; +}; + +template<class T> +class Index : private IndexBase +{ +private: + // provides C-style callback to generic comparison functor + template<class Key, class F> + struct WrapCompare + { + static int run(const void * key, const void * val, void * func) + { + return (*(F *)func)(*(const Key *)key, *(const T *)val); + } + }; + +public: + constexpr Index() : IndexBase() {} + + // use with care! + IndexBase & base() { return *this; } + + void clear() { IndexBase::clear(aud::erase_func<T>()); } + ~Index() { clear(); } + + Index(Index && b) : IndexBase(std::move(b)) {} + Index & operator=(Index && b) + { + return aud::move_assign(*this, std::move(b)); + } + + T * begin() { return (T *)IndexBase::begin(); } + const T * begin() const { return (const T *)IndexBase::begin(); } + T * end() { return (T *)IndexBase::end(); } + const T * end() const { return (const T *)IndexBase::end(); } + + int len() const { return cooked(IndexBase::len()); } + + T & operator[](int i) { return begin()[i]; } + const T & operator[](int i) const { return begin()[i]; } + + void insert(int pos, int len) + { + IndexBase::insert(raw(pos), raw(len), aud::fill_func<T>()); + } + void insert(const T * from, int pos, int len) + { + IndexBase::insert(from, raw(pos), raw(len), aud::copy_func<T>()); + } + void remove(int pos, int len) + { + IndexBase::remove(raw(pos), raw(len), aud::erase_func<T>()); + } + void erase(int pos, int len) + { + IndexBase::erase(raw(pos), raw(len), aud::fill_func<T>(), + aud::erase_func<T>()); + } + void shift(int from, int to, int len) + { + IndexBase::shift(raw(from), raw(to), raw(len), aud::fill_func<T>(), + aud::erase_func<T>()); + } + + void move_from(Index<T> & b, int from, int to, int len, bool expand, + bool collapse) + { + IndexBase::move_from(b, raw(from), raw(to), raw(len), expand, collapse, + aud::fill_func<T>(), aud::erase_func<T>()); + } + + template<class... Args> + T & append(Args &&... args) + { + return *aud::construct<T>::make(IndexBase::insert(-1, sizeof(T)), + std::forward<Args>(args)...); + } + + int find(const T & val) const + { + for (const T * iter = begin(); iter != end(); iter++) + { + if (*iter == val) + return iter - begin(); + } + + return -1; + } + + // func(val) returns true to remove val, false to keep it + template<class F> + bool remove_if(F func, bool clear_if_empty = false) + { + T * iter = begin(); + bool changed = false; + while (iter != end()) + { + if (func(*iter)) + { + remove(iter - begin(), 1); + changed = true; + } + else + iter++; + } + + if (clear_if_empty && !len()) + clear(); + + return changed; + } + + // compare(a, b) returns <0 if a<b, 0 if a=b, >0 if a>b + template<class F> + void sort(F compare) + { + IndexBase::sort(WrapCompare<T, F>::run, sizeof(T), &compare); + } + + // compare(key, val) returns <0 if key<val, 0 if key=val, >0 if key>val + template<class Key, class F> + int bsearch(const Key & key, F compare) + { + return IndexBase::bsearch(&key, WrapCompare<Key, F>::run, sizeof(T), + &compare); + } + + // for use of Index as a raw data buffer + // unlike insert(), does not zero-fill any added space + void resize(int size) + { + static_assert(std::is_trivial<T>::value, "for basic types only"); + int diff = size - len(); + if (diff > 0) + IndexBase::insert(-1, raw(diff)); + else if (diff < 0) + IndexBase::remove(raw(size), -1, nullptr); + } + +private: + static constexpr int raw(int len) { return len * sizeof(T); } + static constexpr int cooked(int len) { return len / sizeof(T); } +}; + +#endif // LIBAUDCORE_INDEX_H diff --git a/src/libaudcore/inifile.cc b/src/libaudcore/inifile.cc new file mode 100644 index 0000000..c7f5da8 --- /dev/null +++ b/src/libaudcore/inifile.cc @@ -0,0 +1,125 @@ +/* + * inifile.c + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "inifile.h" + +#include <string.h> + +#include <glib.h> /* for g_ascii_isspace */ + +#include "audstrings.h" +#include "vfs.h" + +static char * strskip(char * str, char * end) +{ + while (str < end && g_ascii_isspace(*str)) + str++; + + return str; +} + +static char * strtrim(char * str, char * end) +{ + while (end > str && g_ascii_isspace(end[-1])) + end--; + + *end = 0; + return str; +} + +EXPORT void IniParser::parse(VFSFile & file) +{ + int size = 512; + StringBuf buf(size); + + char * pos = buf; + int len = 0; + bool eof = false; + + while (1) + { + char * newline = (char *)memchr(pos, '\n', len); + + while (!newline && !eof) + { + memmove(buf, pos, len); + pos = buf; + + if (len >= size - 1) + { + size <<= 1; + buf.resize(size); + pos = buf; + } + + len += file.fread(buf + len, 1, size - 1 - len); + + if (len < size - 1) + eof = true; + + newline = (char *)memchr(pos, '\n', len); + } + + char * end = newline ? newline : pos + len; + char * start = strskip(pos, end); + char * sep; + + if (start < end) + { + switch (*start) + { + case '#': + case ';': + break; + + case '[': + if ((end = (char *)memchr(start, ']', end - start))) + handle_heading(strtrim(strskip(start + 1, end), end)); + + break; + + default: + if ((sep = (char *)memchr(start, '=', end - start))) + handle_entry(strtrim(start, sep), + strtrim(strskip(sep + 1, end), end)); + + break; + } + } + + if (!newline) + break; + + len -= newline + 1 - pos; + pos = newline + 1; + } +} + +EXPORT bool inifile_write_heading(VFSFile & file, const char * heading) +{ + StringBuf line = str_concat({"\n[", heading, "]\n"}); + return (file.fwrite(line, 1, line.len()) == line.len()); +} + +EXPORT bool inifile_write_entry(VFSFile & file, const char * key, + const char * value) +{ + StringBuf line = str_concat({key, "=", value, "\n"}); + return (file.fwrite(line, 1, line.len()) == line.len()); +} diff --git a/src/libaudcore/inifile.h b/src/libaudcore/inifile.h new file mode 100644 index 0000000..aa28794 --- /dev/null +++ b/src/libaudcore/inifile.h @@ -0,0 +1,44 @@ +/* + * inifile.h + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_INIFILE_H +#define LIBAUDCORE_INIFILE_H + +#include <libaudcore/export.h> + +class VFSFile; + +class LIBAUDCORE_PUBLIC IniParser +{ +public: + virtual ~IniParser() {} + + void parse(VFSFile & file); + +protected: + virtual void handle_heading(const char * heading) = 0; + virtual void handle_entry(const char * key, const char * value) = 0; +}; + +bool inifile_write_heading(VFSFile & file, const char * heading) + __attribute__((warn_unused_result)); +bool inifile_write_entry(VFSFile & file, const char * key, const char * value) + __attribute__((warn_unused_result)); + +#endif /* LIBAUDCORE_INIFILE_H */ diff --git a/src/libaudcore/interface.cc b/src/libaudcore/interface.cc new file mode 100644 index 0000000..ce4e5b2 --- /dev/null +++ b/src/libaudcore/interface.cc @@ -0,0 +1,244 @@ +/* + * interface.c + * Copyright 2010-2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "interface.h" +#include "internal.h" + +#include <assert.h> +#include <glib.h> + +#include "drct.h" +#include "hook.h" +#include "mainloop.h" +#include "plugin.h" +#include "plugins.h" +#include "runtime.h" + +struct MenuItem +{ + const char * name; + const char * icon; + void (*func)(); +}; + +static PluginHandle * current_plugin; +static IfacePlugin * current_interface; + +static aud::array<AudMenuID, Index<MenuItem>> menu_items; + +static void add_menu_items() +{ + for (AudMenuID id : aud::range<AudMenuID>()) + { + for (MenuItem & item : menu_items[id]) + current_interface->plugin_menu_add(id, item.func, item.name, + item.icon); + } +} + +static void remove_menu_items() +{ + for (AudMenuID id : aud::range<AudMenuID>()) + { + for (MenuItem & item : menu_items[id]) + current_interface->plugin_menu_remove(id, item.func); + } +} + +static bool interface_load(PluginHandle * plugin) +{ + auto i = (IfacePlugin *)aud_plugin_get_header(plugin); + if (!i) + return false; + + AUDINFO("Loading %s.\n", aud_plugin_get_name(plugin)); + + if (!i->init()) + return false; + + current_interface = i; + + add_menu_items(); + + if (aud_get_bool("show_interface")) + current_interface->show(true); + + return true; +} + +static void interface_unload() +{ + AUDINFO("Unloading %s.\n", aud_plugin_get_name(current_plugin)); + + // call before unloading interface + hook_call("config save", nullptr); + + if (aud_get_bool("show_interface")) + current_interface->show(false); + + remove_menu_items(); + + current_interface->cleanup(); + current_interface = nullptr; +} + +EXPORT void aud_ui_show(bool show) +{ + if (!current_interface) + return; + + aud_set_bool("show_interface", show); + + current_interface->show(show); + + vis_activate(show); +} + +EXPORT bool aud_ui_is_shown() +{ + if (!current_interface) + return false; + + return aud_get_bool("show_interface"); +} + +EXPORT void aud_ui_startup_notify(const char * id) +{ + if (current_interface) + current_interface->startup_notify(id); +} + +EXPORT void aud_ui_show_error(const char * message) +{ + if (aud_get_headless_mode()) + AUDERR("%s\n", message); + else + event_queue("ui show error", g_strdup(message), g_free); +} + +PluginHandle * iface_plugin_get_current() { return current_plugin; } + +bool iface_plugin_set_current(PluginHandle * plugin) +{ + if (current_interface) + interface_unload(); + + if (!interface_load(plugin)) + return false; + + current_plugin = plugin; + return true; +} + +void interface_run() +{ + if (aud_get_headless_mode()) + { + mainloop_run(); + + // call before shutting down + hook_call("config save", nullptr); + } + else if (current_interface) + { + vis_activate(aud_get_bool("show_interface")); + + current_interface->run(); + interface_unload(); + } +} + +EXPORT void aud_quit() +{ + // Qt is very sensitive to things being deleted in the correct order + // to avoid upsetting it, we'll stop all queued callbacks right now + QueuedFunc::inhibit_all(); + + if (current_interface) + current_interface->quit(); + else + mainloop_quit(); +} + +EXPORT void aud_plugin_menu_add(AudMenuID id, void (*func)(), const char * name, + const char * icon) +{ + menu_items[id].append(name, icon, func); + + if (current_interface) + current_interface->plugin_menu_add(id, func, name, icon); +} + +EXPORT void aud_plugin_menu_remove(AudMenuID id, void (*func)()) +{ + if (current_interface) + current_interface->plugin_menu_remove(id, func); + + auto is_match = [=](const MenuItem & item) { return item.func == func; }; + + menu_items[id].remove_if(is_match, true); +} + +EXPORT void aud_ui_show_about_window() +{ + if (current_interface) + current_interface->show_about_window(); +} + +EXPORT void aud_ui_hide_about_window() +{ + if (current_interface) + current_interface->hide_about_window(); +} + +EXPORT void aud_ui_show_filebrowser(bool open) +{ + if (current_interface) + current_interface->show_filebrowser(open); +} + +EXPORT void aud_ui_hide_filebrowser() +{ + if (current_interface) + current_interface->hide_filebrowser(); +} + +EXPORT void aud_ui_show_jump_to_song() +{ + if (current_interface) + current_interface->show_jump_to_song(); +} + +EXPORT void aud_ui_hide_jump_to_song() +{ + if (current_interface) + current_interface->hide_jump_to_song(); +} + +EXPORT void aud_ui_show_prefs_window() +{ + if (current_interface) + current_interface->show_prefs_window(); +} + +EXPORT void aud_ui_hide_prefs_window() +{ + if (current_interface) + current_interface->hide_prefs_window(); +} diff --git a/src/libaudcore/interface.h b/src/libaudcore/interface.h new file mode 100644 index 0000000..0a8821d --- /dev/null +++ b/src/libaudcore/interface.h @@ -0,0 +1,56 @@ +/* + * interface.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_INTERFACE_H +#define LIBAUDCORE_INTERFACE_H + +#include <libaudcore/visualizer.h> + +enum class AudMenuID +{ + Main, + Playlist, + PlaylistAdd, + PlaylistRemove, + count +}; + +void aud_ui_show(bool show); +bool aud_ui_is_shown(); + +void aud_ui_startup_notify(const char * id); +void aud_ui_show_error(const char * message); /* thread-safe */ + +void aud_ui_show_about_window(); +void aud_ui_hide_about_window(); +void aud_ui_show_filebrowser(bool open); +void aud_ui_hide_filebrowser(); +void aud_ui_show_jump_to_song(); +void aud_ui_hide_jump_to_song(); +void aud_ui_show_prefs_window(); +void aud_ui_hide_prefs_window(); + +void aud_plugin_menu_add(AudMenuID id, void (*func)(), const char * name, + const char * icon); +void aud_plugin_menu_remove(AudMenuID id, void (*func)()); + +void aud_visualizer_add(Visualizer * vis); +void aud_visualizer_remove(Visualizer * vis); + +#endif diff --git a/src/libaudcore/internal.h b/src/libaudcore/internal.h new file mode 100644 index 0000000..29aebcb --- /dev/null +++ b/src/libaudcore/internal.h @@ -0,0 +1,164 @@ +/* + * internal.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_INTERNAL_H +#define LIBAUDCORE_INTERNAL_H + +#include <stdint.h> +#include <sys/types.h> + +#include "index.h" +#include "objects.h" + +class InputPlugin; +class Plugin; +class PluginHandle; +class VFSFile; +class Tuple; + +typedef bool (*DirForeachFunc)(const char * path, const char * basename, + void * user); + +/* adder.cc */ +void adder_cleanup(); + +/* art.cc */ +void art_cache_current(const String & filename, Index<char> && data, + String && art_file); +void art_clear_current(); +void art_cleanup(); + +/* art-search.cc */ +String art_search(const char * filename); + +/* charset.cc */ +void chardet_init(); +void chardet_cleanup(); + +/* config.cc */ +void config_load(); +void config_save(); +void config_cleanup(); + +/* drct.cc */ +void record_init(); +void record_cleanup(); + +/* effect.cc */ +void effect_start(int & channels, int & rate); +Index<float> & effect_process(Index<float> & data); +bool effect_flush(bool force); +Index<float> & effect_finish(Index<float> & data, bool end_of_playlist); +int effect_adjust_delay(int delay); + +bool effect_plugin_start(PluginHandle * plugin); +void effect_plugin_stop(PluginHandle * plugin); + +/* equalizer.cc */ +void eq_init(); +void eq_cleanup(); +void eq_set_format(int new_channels, int new_rate); +void eq_filter(float * data, int samples); + +/* eventqueue.cc */ +void event_queue_pause(); +void event_queue_unpause(); +void event_queue_cancel_all(); + +/* fft.cc */ +void calc_freq(const float data[512], float freq[256]); + +/* hook.cc */ +void hook_cleanup(); + +/* interface.cc */ +PluginHandle * iface_plugin_probe(); +PluginHandle * iface_plugin_get_current(); +bool iface_plugin_set_current(PluginHandle * plugin); + +void interface_run(); + +/* playback.cc */ +/* do not call these; use aud_drct_play/stop() instead */ +void playback_play(int seek_time, bool pause); +void playback_stop(bool exiting = false); + +bool playback_check_serial(int serial); +void playback_set_info(int entry, Tuple && tuple); + +/* probe.cc */ +bool open_input_file(const char * filename, const char * mode, InputPlugin * ip, + VFSFile & file, String * error = nullptr); +InputPlugin * load_input_plugin(PluginHandle * decoder, + String * error = nullptr); + +#define PROBE_FLAG_HAS_DECODER (1 << 0) +#define PROBE_FLAG_MIGHT_HAVE_SUBTUNES (1 << 1) +int probe_by_filename(const char * filename); + +/* runtime.cc */ +extern size_t misc_bytes_allocated; + +/* strpool.cc */ +void string_leak_check(); + +/* timer.cc */ +void timer_cleanup(); + +/* util.cc */ +const char * get_home_utf8(); +bool dir_foreach(const char * path, DirForeachFunc func, void * user_data); +String write_temp_file(const void * data, int64_t len); + +bool same_basename(const char * a, const char * b); +const char * last_path_element(const char * path); +void cut_path_element(char * path, int pos); + +bool is_cuesheet_entry(const char * filename); +bool is_subtune(const char * filename); +StringBuf strip_subtune(const char * filename); + +unsigned int32_hash(unsigned val); +unsigned ptr_hash(const void * ptr); + +struct IntHashKey +{ + int val; + + constexpr IntHashKey(int val) : val(val) {} + operator int() const { return val; } + unsigned hash() const { return int32_hash(val); } +}; + +/* vis-runner.cc */ +void vis_runner_start_stop(bool playing, bool paused); +void vis_runner_pass_audio(int time, const Index<float> & data, int channels, + int rate); +void vis_runner_flush(); +void vis_runner_enable(bool enable); + +/* visualization.cc */ +void vis_activate(bool activate); +void vis_send_clear(); +void vis_send_audio(const float * data, int channels); + +bool vis_plugin_start(PluginHandle * plugin); +void vis_plugin_stop(PluginHandle * plugin); + +#endif diff --git a/src/libaudcore/list.cc b/src/libaudcore/list.cc new file mode 100644 index 0000000..f5a64e2 --- /dev/null +++ b/src/libaudcore/list.cc @@ -0,0 +1,77 @@ +/* + * list.cpp + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "list.h" + +EXPORT void ListBase::insert_after(ListNode * prev, ListNode * node) +{ + ListNode * next; + + if (prev) + { + next = prev->next; + prev->next = node; + } + else + { + next = head; + head = node; + } + + node->prev = prev; + node->next = next; + + if (next) + next->prev = node; + else + tail = node; +} + +EXPORT void ListBase::remove(ListNode * node) +{ + ListNode * prev = node->prev; + ListNode * next = node->next; + + node->prev = nullptr; + node->next = nullptr; + + if (prev) + prev->next = next; + else + head = next; + + if (next) + next->prev = prev; + else + tail = prev; +} + +EXPORT void ListBase::clear(DestroyFunc destroy) +{ + ListNode * node = head; + while (node) + { + ListNode * next = node->next; + destroy(node); + node = next; + } + + head = nullptr; + tail = nullptr; +} diff --git a/src/libaudcore/list.h b/src/libaudcore/list.h new file mode 100644 index 0000000..90ef9af --- /dev/null +++ b/src/libaudcore/list.h @@ -0,0 +1,93 @@ +/* + * list.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_LIST_H +#define LIBAUDCORE_LIST_H + +struct ListNode +{ + friend class ListBase; + +private: + ListNode * prev = nullptr; + ListNode * next = nullptr; +}; + +class ListBase +{ +protected: + typedef void (*DestroyFunc)(ListNode *); + + ListNode * head = nullptr; + ListNode * tail = nullptr; + + void insert_after(ListNode * prev, ListNode * node); + void remove(ListNode * node); + void clear(DestroyFunc destroy); + + static ListNode * prev(ListNode * node) { return node->prev; } + static ListNode * next(ListNode * node) { return node->next; } +}; + +template<class C> +class List : private ListBase +{ +public: + C * head() const { return (C *)ListBase::head; } + C * tail() const { return (C *)ListBase::tail; } + + static C * prev(C * node) { return (C *)ListBase::prev(node); } + static C * next(C * node) { return (C *)ListBase::next(node); } + + void insert_after(C * prev, C * node) + { + ListBase::insert_after(prev, node); + } + void remove(C * node) { ListBase::remove(node); } + + void prepend(C * node) { insert_after(nullptr, node); } + void append(C * node) { insert_after(tail(), node); } + + void clear() { ListBase::clear(destroy); } + + C * pop_head() + { + C * node = head(); + if (node) + remove(node); + return node; + } + + template<class MatchFunc> + C * find(MatchFunc match) + { + for (C * node = head(); node; node = next(node)) + { + if (match(*node)) + return node; + } + + return nullptr; + } + +private: + static void destroy(ListNode * node) { delete (C *)node; } +}; + +#endif // LIBAUDCORE_LIST_H diff --git a/src/libaudcore/logger.cc b/src/libaudcore/logger.cc new file mode 100644 index 0000000..d00a5af --- /dev/null +++ b/src/libaudcore/logger.cc @@ -0,0 +1,120 @@ +/* + * logger.cc + * Copyright 2014 John Lindgren and Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "audstrings.h" +#include "index.h" +#include "runtime.h" +#include "threads.h" + +#include <stdio.h> + +namespace audlog +{ + +struct HandlerData +{ + Handler handler; + Level level; +}; + +static aud::spinlock_rw lock; +static Index<HandlerData> handlers; +static Level stderr_level = Warning; +static Level min_level = Warning; + +EXPORT void set_stderr_level(Level level) +{ + auto wr = lock.write(); + min_level = stderr_level = level; + + for (const HandlerData & h : handlers) + { + if (h.level < min_level) + min_level = h.level; + } +} + +EXPORT void subscribe(Handler handler, Level level) +{ + auto wr = lock.write(); + handlers.append(handler, level); + + if (level < min_level) + min_level = level; +} + +EXPORT void unsubscribe(Handler handler) +{ + auto is_match = [handler](const HandlerData & data) { + return data.handler == handler; + }; + + auto wr = lock.write(); + handlers.remove_if(is_match, true); + min_level = stderr_level; + + for (const HandlerData & h : handlers) + { + if (h.level < min_level) + min_level = h.level; + } +} + +EXPORT const char * get_level_name(Level level) +{ + switch (level) + { + case Debug: + return "DEBUG"; + case Info: + return "INFO"; + case Warning: + return "WARNING"; + case Error: + return "ERROR"; + }; + + return nullptr; +} + +EXPORT void log(Level level, const char * file, int line, const char * func, + const char * format, ...) +{ + auto rd = lock.read(); + + if (level >= min_level) + { + va_list args; + va_start(args, format); + StringBuf message = str_vprintf(format, args); + va_end(args); + + if (level >= stderr_level) + fprintf(stderr, "%s %s:%d [%s]: %s", get_level_name(level), file, + line, func, (const char *)message); + + for (const HandlerData & h : handlers) + { + if (level >= h.level) + h.handler(level, file, line, func, message); + } + } +} + +} // namespace audlog diff --git a/src/libaudcore/mainloop.cc b/src/libaudcore/mainloop.cc new file mode 100644 index 0000000..359e561 --- /dev/null +++ b/src/libaudcore/mainloop.cc @@ -0,0 +1,387 @@ +/* + * mainloop.cc + * Copyright 2014-2017 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "mainloop.h" + +#include <glib.h> + +#ifdef USE_QT +#include <QCoreApplication> +#endif + +#include "internal.h" +#include "multihash.h" +#include "runtime.h" + +struct QueuedFuncParams +{ + QueuedFunc::Func func; + void * data; + int interval_ms; + bool repeat; +}; + +// QueuedFunc itself is a tiny handle/identifier object; most of the related +// code lives in various "helper" objects. This is the base class inherited +// by all the different types of helpers. + +struct QueuedFuncHelper +{ + QueuedFunc * queued; + QueuedFuncParams params; + + // Creates an appropriate helper subclass for the given parameters and + // schedules it to run the QueuedFunc + static QueuedFuncHelper * create(QueuedFunc * queued, + const QueuedFuncParams & params); + + // Callback which runs the QueuedFunc, if still active + void run(); + + // Cancels any scheduled run of the QueuedFunc and marks the helper for + // deletion (it may not deleted immediately, but should not be accessed + // again after calling this function) + virtual void cancel() = 0; + + virtual ~QueuedFuncHelper() {} + +protected: + QueuedFuncHelper(QueuedFunc * queued, const QueuedFuncParams & params) + : queued(queued), params(params) + { + } +}; + +// The following hash table implements a thread-safe "registry" of active +// QueuedFuncs. This allows a callback executing in the main thread to safely +// look up the information it needs, without accessing the QueuedFunc directly +// and risking use-after-free. + +struct QueuedFuncNode : public MultiHash::Node +{ + // Creates a helper to be registered in the hash + QueuedFuncNode(QueuedFunc * queued, const QueuedFuncParams & params) + : helper(QueuedFuncHelper::create(queued, params)) + { + } + + // Cancels a helper when it is unregistered from the hash + ~QueuedFuncNode() { helper->cancel(); } + + // Replaces the registration of one helper with another + void reset(QueuedFunc * queued, const QueuedFuncParams & params) + { + helper->cancel(); + helper = QueuedFuncHelper::create(queued, params); + } + + // Checks whether a helper is still registered + bool is_current(QueuedFuncHelper * test_helper) const + { + return test_helper == helper; + } + + // Hash comparison function + bool match(const QueuedFunc * queued) const + { + return queued == helper->queued; + } + +private: + QueuedFuncHelper * helper; +}; + +static MultiHash_T<QueuedFuncNode, QueuedFunc> func_table; +static bool in_lockdown = false; + +// Helper logic common between GLib and Qt + +// "run" logic executed within the hash table lock +struct RunCheck +{ + QueuedFuncHelper * helper; + bool okay_to_run; + + // Called if the QueuedFunc is not registered in the hash + // This indicates a "stale" event that should not be processed + QueuedFuncNode * add(const QueuedFunc *) { return nullptr; } + + bool found(const QueuedFuncNode * node) + { + // Check whether a different helper has been registered + // This also indicates a "stale" event that should not be processed + if (!node->is_current(helper)) + return false; + + // We are still registered and good to go + okay_to_run = true; + + // Leave a periodic timer registered + if (helper->params.repeat) + return false; + + // Unregister and cancel a one-time callback + delete node; + return true; + } +}; + +void QueuedFuncHelper::run() +{ + // Check whether it's okay to run. The actual check is performed within + // the MultiHash lock to eliminate race conditions. + RunCheck r = {this, false}; + func_table.lookup(queued, ptr_hash(queued), r); + + if (r.okay_to_run) + params.func(params.data); +} + +// GLib implementation -- simple wrapper around g_timeout_add_full() + +class HelperGLib : public QueuedFuncHelper +{ +public: + HelperGLib(QueuedFunc * queued, const QueuedFuncParams & params) + : QueuedFuncHelper(queued, params) + { + glib_source = + g_timeout_add_full(G_PRIORITY_HIGH, params.interval_ms, run_cb, + this, aud::delete_obj<HelperGLib>); + } + + void cancel() + { + // GLib will delete the helper after we return to the main loop + g_source_remove(glib_source); + } + +private: + static gboolean run_cb(void * me) + { + (static_cast<HelperGLib *>(me))->run(); + return G_SOURCE_CONTINUE; + } + + int glib_source = 0; +}; + +#ifdef USE_QT + +// Qt implementation -- rather more complicated + +// One-time callbacks are implemented through custom events posted to a "router" +// object. In this case, the QueuedFuncHelper class is the QEvent itself. The +// router object is created in, and associated with, the main thread, thus +// events are executed in the main thread regardless of their origin. Events +// can be queued even before the QApplication has been created. Note that +// QEvents cannot be cancelled once posted; therefore it's necessary to check +// on our side that the QueuedFunc is still active when the event is received. + +class EventRouter : public QObject +{ +protected: + void customEvent(QEvent * event); +}; + +static EventRouter router; + +class HelperQEvent : public QueuedFuncHelper, public QEvent +{ +public: + HelperQEvent(QueuedFunc * queued, const QueuedFuncParams & params) + : QueuedFuncHelper(queued, params), QEvent(User) + { + QCoreApplication::postEvent(&router, this, Qt::HighEventPriority); + } + + void cancel() {} // Qt will delete the event after it fires +}; + +void EventRouter::customEvent(QEvent * event) +{ + dynamic_cast<HelperQEvent *>(event)->run(); +} + +// Periodic callbacks are implemented through QObject's timer capability. In +// this case, the QueuedFuncHelper is a QObject that is re-associated with the +// main thread immediately after creation. The timer is started in a roundabout +// fashion due to the fact that QObject::startTimer() does not work until the +// QApplication has been created. To work around this, a single QEvent is first +// posted. When this initial event is executed (in the main thread), we know +// that the QApplication is up. We then start the timer and run our own +// callback from the QTimerEvents we receive. + +class HelperQTimer : public QueuedFuncHelper, public QObject +{ +public: + HelperQTimer(QueuedFunc * queued, const QueuedFuncParams & params) + : QueuedFuncHelper(queued, params) + { + moveToThread(router.thread()); // main thread + QCoreApplication::postEvent(this, new QEvent(QEvent::User), + Qt::HighEventPriority); + } + + void cancel() { deleteLater(); } + +protected: + void customEvent(QEvent *) { startTimer(params.interval_ms); } + void timerEvent(QTimerEvent *) { run(); } +}; + +#endif // USE_QT + +// creates the appropriate helper subclass +QueuedFuncHelper * QueuedFuncHelper::create(QueuedFunc * queued, + const QueuedFuncParams & params) +{ +#ifdef USE_QT + if (aud_get_mainloop_type() == MainloopType::Qt) + { + if (params.interval_ms > 0) + return new HelperQTimer(queued, params); + else + return new HelperQEvent(queued, params); + } +#endif + + return new HelperGLib(queued, params); +} + +// "start" logic executed within the hash table lock +struct Starter +{ + QueuedFunc * queued; + const QueuedFuncParams & params; + + // register a new helper for this QueuedFunc + QueuedFuncNode * add(const QueuedFunc *) + { + return in_lockdown ? nullptr : new QueuedFuncNode(queued, params); + } + + // cancel the old helper and register a replacement + bool found(QueuedFuncNode * node) + { + node->reset(queued, params); + return false; + } +}; + +// common entry point used by all queue() and start() variants +static void start_func(QueuedFunc * queued, const QueuedFuncParams & params) +{ + Starter s = {queued, params}; + func_table.lookup(queued, ptr_hash(queued), s); +} + +EXPORT void QueuedFunc::queue(Func func, void * data) +{ + start_func(this, {func, data, 0, false}); + _running = false; +} + +EXPORT void QueuedFunc::queue(int delay_ms, Func func, void * data) +{ + g_return_if_fail(delay_ms >= 0); + start_func(this, {func, data, delay_ms, false}); + _running = false; +} + +EXPORT void QueuedFunc::start(int interval_ms, Func func, void * data) +{ + g_return_if_fail(interval_ms > 0); + start_func(this, {func, data, interval_ms, true}); + _running = true; +} + +// "stop" logic executed within the hash table lock +struct Stopper +{ + // not registered, do nothing + QueuedFuncNode * add(const QueuedFunc *) { return nullptr; } + + // unregister and cancel helper + bool found(QueuedFuncNode * node) + { + delete node; + return true; + } +}; + +EXPORT void QueuedFunc::stop() +{ + Stopper s; + func_table.lookup(this, ptr_hash(this), s); + _running = false; +} + +// unregister a pending callback at shutdown +static bool cleanup_node(QueuedFuncNode * node) +{ + delete node; + return true; +} +// inhibit all future callbacks at shutdown +static void enter_lockdown() { in_lockdown = true; } + +EXPORT void QueuedFunc::inhibit_all() +{ + func_table.iterate(cleanup_node, enter_lockdown); +} + +// main loop implementation follows + +static GMainLoop * glib_mainloop; + +EXPORT void mainloop_run() +{ +#ifdef USE_QT + if (aud_get_mainloop_type() == MainloopType::Qt) + { + static char app_name[] = "audacious"; + static int dummy_argc = 1; + static char * dummy_argv[] = {app_name, nullptr}; + + QCoreApplication(dummy_argc, dummy_argv).exec(); + } + else +#endif + { + glib_mainloop = g_main_loop_new(nullptr, true); + g_main_loop_run(glib_mainloop); + g_main_loop_unref(glib_mainloop); + glib_mainloop = nullptr; + } +} + +EXPORT void mainloop_quit() +{ +#ifdef USE_QT + if (aud_get_mainloop_type() == MainloopType::Qt) + { + qApp->quit(); + } + else +#endif + { + g_main_loop_quit(glib_mainloop); + } +} diff --git a/src/libaudcore/mainloop.h b/src/libaudcore/mainloop.h new file mode 100644 index 0000000..2d74e28 --- /dev/null +++ b/src/libaudcore/mainloop.h @@ -0,0 +1,67 @@ +/* + * mainloop.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +/* Main loop abstraction layer which can use either GLib or Qt as a backend. + * The API is completely thread-safe and can thus be used as a means to call + * back into the main thread from a worker thread. */ + +#ifndef LIBAUDCORE_MAINLOOP_H +#define LIBAUDCORE_MAINLOOP_H + +class QueuedFunc +{ +public: + typedef void (*Func)(void * data); + + // one-time idle callback + void queue(Func func, void * data); + + // one-time delayed callback + void queue(int delay_ms, Func func, void * data); + + // periodic timer callback + void start(int interval_ms, Func func, void * data); + + // stops any type of callback + // note that queue() and start() also stop any previous callback + void stop(); + + // true if a periodic timer is running + // does not apply to one-time callbacks + bool running() const { return _running; } + + constexpr QueuedFunc() = default; + QueuedFunc(const QueuedFunc &) = delete; + void operator=(const QueuedFunc &) = delete; + + ~QueuedFunc() { stop(); } + + // cancels any pending callbacks + // inhibits all future callbacks + // needed to allow safe shutdown of some (Qt!) main loops + static void inhibit_all(); + +private: + bool _running = false; +}; + +void mainloop_run(); +void mainloop_quit(); + +#endif // LIBAUDCORE_MAINLOOP_H diff --git a/src/libaudcore/meson.build b/src/libaudcore/meson.build new file mode 100644 index 0000000..9c04bb3 --- /dev/null +++ b/src/libaudcore/meson.build @@ -0,0 +1,126 @@ +libaudcore_inc = include_directories('.') + + +libaudcore_sources = [ + 'adder.cc', + 'art.cc', + 'art-search.cc', + 'audio.cc', + 'audstrings.cc', + 'charset.cc', + 'config.cc', + 'cue-cache.cc', + 'drct.cc', + 'effect.cc', + 'equalizer.cc', + 'equalizer-preset.cc', + 'eventqueue.cc', + 'fft.cc', + 'history.cc', + 'hook.cc', + 'index.cc', + 'inifile.cc', + 'interface.cc', + 'list.cc', + 'logger.cc', + 'mainloop.cc', + 'multihash.cc', + 'output.cc', + 'parse.cc', + 'playback.cc', + 'playlist.cc', + 'playlist-cache.cc', + 'playlist-data.cc', + 'playlist-files.cc', + 'playlist-utils.cc', + 'plugin-init.cc', + 'plugin-load.cc', + 'plugin-registry.cc', + 'preferences.cc', + 'probe.cc', + 'probe-buffer.cc', + 'ringbuf.cc', + 'runtime.cc', + 'scanner.cc', + 'stringbuf.cc', + 'strpool.cc', + 'tinylock.cc', + 'timer.cc', + 'tuple.cc', + 'tuple-compiler.cc', + 'util.cc', + 'vfs.cc', + 'vfs_async.cc', + 'vfs_local.cc', + 'vis-runner.cc', + 'visualization.cc' +] + + +libaudcore_headers = [ + 'audstrings.h', + 'drct.h', + 'equalizer.h', + 'export.h', + 'hook.h', + 'i18n.h', + 'index.h', + 'inifile.h', + 'interface.h', + 'list.h', + 'mainloop.h', + 'multihash.h', + 'objects.h', + 'playlist.h', + 'plugin.h', + 'plugins.h', + 'preferences.h', + 'probe.h', + 'ringbuf.h', + 'runtime.h', + 'templates.h', + 'tinylock.h', + 'threads.h', + 'tuple.h', + 'visualizer.h', + 'vfs.h', + 'vfs_async.h' +] + + +audio_h = configure_file(input: 'audio.h.in', + output: 'audio.h', + configuration: conf, + install: true, + install_dir: join_paths(get_option('includedir'), 'libaudcore')) + + +libaudcore_deps = [glib_dep, gmodule_dep] + +if get_option('qt') + libaudcore_deps += [qt_dep] +endif + + +if cc.has_function('iconv') + iconv_dep = [] +else + iconv_dep = cc.find_library('iconv', required: true) +endif + +libaudcore_deps += [iconv_dep] + + +libaudcore_lib = library('audcore', + libaudcore_sources, + cpp_args: ['-DLIBAUDCORE_BUILD'], + include_directories: src_inc, + dependencies: libaudcore_deps, + link_with: libguess_lib, + version: '5.1.0', + soversion: '5', + install: true +) + + +install_headers(libaudcore_headers, subdir: 'libaudcore') diff --git a/src/libaudcore/multihash.cc b/src/libaudcore/multihash.cc new file mode 100644 index 0000000..2068a6c --- /dev/null +++ b/src/libaudcore/multihash.cc @@ -0,0 +1,179 @@ +/* + * multihash.c + * Copyright 2013-2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "multihash.h" + +EXPORT void HashBase::add(Node * node, unsigned hash) +{ + if (!buckets) + { + buckets = new Node *[InitialSize](); + size = InitialSize; + } + + unsigned b = hash & (size - 1); + node->next = buckets[b]; + node->hash = hash; + buckets[b] = node; + + used++; + if (used > size) + resize(size << 1); +} + +EXPORT HashBase::Node * HashBase::lookup(MatchFunc match, const void * data, + unsigned hash, NodeLoc * loc) const +{ + if (!buckets) + return nullptr; + + unsigned b = hash & (size - 1); + Node ** node_ptr = &buckets[b]; + Node * node = *node_ptr; + + while (1) + { + if (!node) + return nullptr; + + if (node->hash == hash && match(node, data)) + break; + + node_ptr = &node->next; + node = *node_ptr; + } + + if (loc) + { + loc->ptr = node_ptr; + loc->next = node->next; + } + + return node; +} + +EXPORT void HashBase::remove(const NodeLoc & loc) +{ + *loc.ptr = loc.next; + + used--; + if (used<size>> 2 && size > InitialSize) + resize(size >> 1); +} + +EXPORT void HashBase::iterate(FoundFunc func, void * state) +{ + for (unsigned b = 0; b < size; b++) + { + Node ** ptr = &buckets[b]; + Node * node = *ptr; + + while (node) + { + Node * next = node->next; + + if (func(node, state)) + { + *ptr = next; + used--; + } + else + ptr = &node->next; + + node = next; + } + } + + if (used<size>> 2 && size > InitialSize) + resize(size >> 1); +} + +void HashBase::resize(unsigned new_size) +{ + Node ** new_buckets = new Node *[new_size](); + + for (unsigned b1 = 0; b1 < size; b1++) + { + Node * node = buckets[b1]; + + while (node) + { + Node * next = node->next; + + unsigned b2 = node->hash & (new_size - 1); + node->next = new_buckets[b2]; + new_buckets[b2] = node; + + node = next; + } + } + + delete[] buckets; + buckets = new_buckets; + size = new_size; +} + +EXPORT int MultiHash::lookup(const void * data, unsigned hash, AddFunc add, + FoundFunc found, void * state) +{ + const unsigned c = (hash >> Shift) & (Channels - 1); + HashBase & channel = channels[c]; + + int status = 0; + auto lh = locks[c].take(); + + HashBase::NodeLoc loc; + Node * node = channel.lookup(match, data, hash, &loc); + + if (node) + { + status |= Found; + if (found && found(node, state)) + { + status |= Removed; + channel.remove(loc); + } + } + else if (add && (node = add(data, state))) + { + status |= Added; + channel.add(node, hash); + } + + return status; +} + +EXPORT void MultiHash::iterate(FoundFunc func, void * state) +{ + iterate(func, state, nullptr, nullptr); +} + +EXPORT void MultiHash::iterate(FoundFunc func, void * state, FinalFunc final, + void * fstate) +{ + aud::spinlock::holder lh[Channels]; + for (int i = 0; i < Channels; i++) + lh[i] = locks[i].take(); + + for (HashBase & channel : channels) + channel.iterate(func, state); + + if (final) + final(fstate); +} diff --git a/src/libaudcore/multihash.h b/src/libaudcore/multihash.h new file mode 100644 index 0000000..d370a27 --- /dev/null +++ b/src/libaudcore/multihash.h @@ -0,0 +1,339 @@ +/* + * multihash.h + * Copyright 2013-2017 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_MULTIHASH_H +#define LIBAUDCORE_MULTIHASH_H + +#include <libaudcore/threads.h> +#include <utility> + +/* HashBase is a low-level hash table implementation. It is used as a backend + * for SimpleHash as well as for a single channel of MultiHash. */ + +class HashBase +{ +public: + /* Skeleton structure containing internal members of a hash node (except for + * "refs", which is not used internally and included here only to fill an + * alignment gap). Actual node structures should subclass Node. */ + struct Node + { + Node * next; + unsigned hash; + unsigned refs; + }; + + /* Represents the location of a node within the table. */ + struct NodeLoc + { + Node ** ptr; + Node * next; + }; + + /* Callback. Returns true if <node> matches <data>, otherwise false. */ + typedef bool (*MatchFunc)(const Node * node, const void * data); + + /* Callback. Called when a node is found. Returns true if <node> is to be + * removed, otherwise false. */ + typedef bool (*FoundFunc)(Node * node, void * state); + + constexpr HashBase() : buckets(nullptr), size(0), used(0) {} + + void clear() // use as destructor + { + delete[] buckets; + *this = HashBase(); + } + + int n_items() const { return used; } + + /* Adds a node. Does not check for duplicates. */ + void add(Node * node, unsigned hash); + + /* Locates the node matching <data>. Returns null if no node is found. If + * <loc> is not null, also returns the location of the node, which can be + * used to remove it from the table. */ + Node * lookup(MatchFunc match, const void * data, unsigned hash, + NodeLoc * loc = nullptr) const; + + /* Removes a node, given a location returned by lookup_full(). */ + void remove(const NodeLoc & loc); + + /* Iterates over all nodes in the table, removing them as desired. */ + void iterate(FoundFunc func, void * state); + +private: + static constexpr unsigned InitialSize = 16; + + void resize(unsigned new_size); + + Node ** buckets; + unsigned size, used; +}; + +/* MultiHash is a generic, thread-safe hash table. It scales well to multiple + * processors by the use of multiple channels, each with a separate lock. The + * hash value of a given node decides what channel it is stored in. Hence, + * different processors will tend to hit different channels, keeping lock + * contention to a minimum. The all-purpose lookup function enables a variety + * of atomic operations, such as allocating and adding a node only if not + * already present. */ + +class MultiHash +{ +public: + static constexpr int Found = 1 << 0; + static constexpr int Added = 1 << 1; + static constexpr int Removed = 1 << 2; + + typedef HashBase::Node Node; + typedef HashBase::MatchFunc MatchFunc; + typedef HashBase::FoundFunc FoundFunc; + typedef void (*FinalFunc)(void * state); + + /* Callback. May create a new node representing <data> to be added to the + * table. Returns the new node or null. */ + typedef Node * (*AddFunc)(const void * data, void * state); + + MultiHash(MatchFunc match) : match(match), locks(), channels() {} + + /* There is no destructor. In some instances, such as the string pool, it + * is never safe to destroy the hash table, since it can be referenced from + * the destructors of other static objects. It is left to the operating + * system to reclaim the memory used by the hash table upon process exit. */ + + /* All-purpose lookup function. The caller passes in the data to be looked + * up along with its hash value. The two callbacks are optional. <add> is + * called if no matching node is found, and may return a new node to add to + * the table. <found> is called if a matching node is found, and may return + * true to remove the node from the table. Returns the status of the lookup + * as a bitmask of Found, Added, and Removed. */ + int lookup(const void * data, unsigned hash, AddFunc add, FoundFunc found, + void * state); + + /* All-purpose iteration function. All channels of the table are locked + * simultaneously during the iteration to freeze the table in a consistent + * state. <func> is called on each node in order, and may return true to + * remove the node from the table. */ + void iterate(FoundFunc func, void * state); + + /* Variant of iterate() which runs a second callback after the iteration + * is complete, while the table is still locked. This is useful when some + * operation needs to be performed with the table in a known state. */ + void iterate(FoundFunc func, void * state, FinalFunc final, void * fstate); + +private: + static constexpr int Channels = 16; /* must be a power of two */ + static constexpr int Shift = 24; /* bit shift for channel selection */ + + const MatchFunc match; + aud::spinlock locks[Channels]; + HashBase channels[Channels]; +}; + +/* Type-safe version using templates. */ + +template<class Node_T, class Data_T> +class MultiHash_T : private MultiHash +{ +public: + // Required interfaces: + // + // class Node_T : public Node + // { + // bool match (const Data_T * data) const; + // }; + // + // class Operation + // { + // Node_T * add (const Data_T * data); + // bool found (Node_T * node); + // }; + + MultiHash_T() : MultiHash(match_cb) {} + + void clear() { MultiHash::iterate(remove_cb, nullptr); } + + template<class Op> + int lookup(const Data_T * data, unsigned hash, Op & op) + { + return MultiHash::lookup(data, hash, WrapOp<Op>::add, WrapOp<Op>::found, + &op); + } + + template<class F> + void iterate(F func) + { + MultiHash::iterate(WrapIterate<F>::run, &func); + } + + template<class F, class Final> + void iterate(F func, Final final) + { + MultiHash::iterate(WrapIterate<F>::run, &func, WrapFinal<Final>::run, + &final); + } + +private: + static bool match_cb(const Node * node, const void * data) + { + return (static_cast<const Node_T *>(node)) + ->match(static_cast<const Data_T *>(data)); + } + + static bool remove_cb(Node * node, void *) + { + delete static_cast<Node_T *>(node); + return true; + } + + template<class Op> + struct WrapOp + { + static Node * add(const void * data, void * op) + { + return (static_cast<Op *>(op)) + ->add(static_cast<const Data_T *>(data)); + } + static bool found(Node * node, void * op) + { + return (static_cast<Op *>(op))->found(static_cast<Node_T *>(node)); + } + }; + + template<class F> + struct WrapIterate + { + static bool run(Node * node, void * func) + { + return (*static_cast<F *>(func))(static_cast<Node_T *>(node)); + } + }; + + template<class Final> + struct WrapFinal + { + static void run(void * func) { (*static_cast<Final *>(func))(); } + }; +}; + +/* Simpler single-thread hash table. */ + +template<class Key, class Value> +class SimpleHash : private HashBase +{ +public: + typedef void (*IterFunc)(const Key & key, Value & value, void * state); + + ~SimpleHash() { clear(); } + + using HashBase::n_items; + + Value * lookup(const Key & key) + { + auto node = + static_cast<Node *>(HashBase::lookup(match_cb, &key, key.hash())); + return node ? &node->value : nullptr; + } + + Value * add(const Key & key, Value && value) + { + unsigned hash = key.hash(); + auto node = static_cast<Node *>(HashBase::lookup(match_cb, &key, hash)); + + if (node) + node->value = std::move(value); + else + { + node = new Node(key, std::move(value)); + HashBase::add(node, hash); + } + + return &node->value; + } + + void remove(const Key & key) + { + NodeLoc loc; + auto node = static_cast<Node *>( + HashBase::lookup(match_cb, &key, key.hash(), &loc)); + + if (node) + { + delete node; + HashBase::remove(loc); + } + } + + void clear() + { + HashBase::iterate(remove_cb, nullptr); + HashBase::clear(); + } + + template<class F> + void iterate(F func) + { + HashBase::iterate(WrapIterate<F>::run, &func); + } + +private: + struct Node : public HashBase::Node + { + Node(const Key & key, Value && value) + : key(key), value(std::move(value)) + { + } + + Key key; + Value value; + }; + + struct IterData + { + IterFunc func; + void * state; + }; + + static bool match_cb(const HashBase::Node * node, const void * data) + { + return (static_cast<const Node *>(node))->key == + *static_cast<const Key *>(data); + } + + static bool remove_cb(HashBase::Node * node, void *) + { + delete static_cast<Node *>(node); + return true; + } + + // C-style callback wrapping generic iteration functor + template<class F> + struct WrapIterate + { + static bool run(HashBase::Node * node_, void * func) + { + auto node = static_cast<Node *>(node_); + (*static_cast<F *>(func))(node->key, node->value); + return false; + } + }; +}; + +#endif /* LIBAUDCORE_MULTIHASH_H */ diff --git a/src/libaudcore/objects.h b/src/libaudcore/objects.h new file mode 100644 index 0000000..7b79ac6 --- /dev/null +++ b/src/libaudcore/objects.h @@ -0,0 +1,256 @@ +/* + * objects.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_OBJECTS_H +#define LIBAUDCORE_OBJECTS_H + +#ifdef AUD_GLIB_INTEGRATION +#include <glib.h> +#endif + +#include <libaudcore/templates.h> + +// Stores array pointer together with deduced array length. + +template<class T> +struct ArrayRef +{ + const T * data; + int len; + + constexpr ArrayRef(decltype(nullptr) = nullptr) : data(nullptr), len(0) {} + + template<int N> + constexpr ArrayRef(const T (&array)[N]) : data(array), len(N) + { + } + + constexpr ArrayRef(const T * data, int len) : data(data), len(len) {} + + const T * begin() const { return data; } + const T * end() const { return data + len; } +}; + +// Smart pointer. Deletes object pointed to when the pointer goes out of scope. + +template<class T, void (*deleter)(T *) = aud::delete_typed> +class SmartPtr +{ +public: + constexpr SmartPtr() : ptr(nullptr) {} + explicit constexpr SmartPtr(T * ptr) : ptr(ptr) {} + + ~SmartPtr() + { + if (ptr) + deleter(ptr); + } + + bool capture(T * ptr2) + { + if (ptr) + deleter(ptr); + ptr = ptr2; + return (bool)ptr; + } + + T * release() + { + T * ptr2 = ptr; + ptr = nullptr; + return ptr2; + } + + void clear() { capture(nullptr); } + + SmartPtr(SmartPtr && b) : ptr(b.ptr) { b.ptr = nullptr; } + + SmartPtr & operator=(SmartPtr && b) + { + return aud::move_assign(*this, std::move(b)); + } + + explicit operator bool() const { return (bool)ptr; } + + T * get() { return ptr; } + const T * get() const { return ptr; } + T & operator*() { return (*ptr); } + const T & operator*() const { return (*ptr); } + T * operator->() { return ptr; } + const T * operator->() const { return ptr; } + +private: + T * ptr; +}; + +template<class T, class... Args> +SmartPtr<T> SmartNew(Args &&... args) +{ + return SmartPtr<T>(aud::construct<T>::make(operator new(sizeof(T)), + std::forward<Args>(args)...)); +} + +// Convenience wrapper for a GLib-style string (char *). + +#ifdef AUD_GLIB_INTEGRATION +class CharPtr : public SmartPtr<char, aud::typed_func<char, g_free>> +{ +public: + CharPtr() : SmartPtr() {} + explicit CharPtr(char * ptr) : SmartPtr(ptr) {} + + // non-const operator omitted to prevent "CharPtr s; g_free(s);" + operator const char *() const { return get(); } +}; +#endif + +// Wrapper class for a string stored in the string pool. + +class String +{ +public: + constexpr String() : raw(nullptr) {} + + ~String() + { + if (raw) + raw_unref(raw); + } + + String(const String & b) : raw(raw_ref(b.raw)) {} + + String & operator=(const String & b) + { + if (this != &b) + { + raw_unref(raw); + raw = raw_ref(b.raw); + } + return *this; + } + + String(String && b) : raw(b.raw) { b.raw = nullptr; } + + String & operator=(String && b) + { + return aud::move_assign(*this, std::move(b)); + } + + bool operator==(const String & b) const { return raw_equal(raw, b.raw); } + + explicit String(const char * str) : raw(raw_get(str)) {} + + String(decltype(nullptr)) = delete; + + operator const char *() const { return raw; } + + unsigned hash() const { return raw_hash(raw); } + +private: + static char * raw_get(const char * str); + static char * raw_ref(const char * str); + static void raw_unref(char * str); + static unsigned raw_hash(const char * str); + static bool raw_equal(const char * str1, const char * str2); + + char * raw; +}; + +struct StringStack; + +// Mutable string buffer, allocated on a stack-like structure. The intent is +// to provide fast allocation/deallocation for strings with a short lifespan. +// Note that some usage patterns (for example, repeatedly appending to multiple +// strings) can rapidly cause memory fragmentation and eventually lead to an +// out-of-memory exception. +// +// Some usage guidelines: +// +// 1. Always declare StringBufs within function or block scope, never at file +// or class scope. Do not attempt to create a StringBuf with new or +// malloc(). +// 2. If you need to return a StringBuf from a function that uses several +// different strings internally, make sure all the other strings go out of +// scope first and then call settle() on the string to be returned. +// 3. Never transfer StringBuf objects across thread boundaries. + +class StringBuf +{ +public: + constexpr StringBuf() : stack(nullptr), m_data(nullptr), m_len(0) {} + + explicit StringBuf(int len) : stack(nullptr), m_data(nullptr), m_len(0) + { + resize(len); + } + + StringBuf(StringBuf && other) + : stack(other.stack), m_data(other.m_data), m_len(other.m_len) + { + other.stack = nullptr; + other.m_data = nullptr; + other.m_len = 0; + } + + StringBuf & operator=(StringBuf && other) + { + return aud::move_assign(*this, std::move(other)); + } + + ~StringBuf(); + + // Resizes to <len> bytes (not counting the terminating null byte) by + // appended uninitialized bytes or truncating. The resized string will be + // null-terminated unless <len> is -1. A length of -1 means to make the + // string as large as possible. This can be useful when the required length + // is not known in advance. However, it will be impossible to create any + // further StringBufs until resize() is called again. + void resize(int len); + + // Inserts the substring <s> at the given position, or appends it if <pos> + // is -1. If <len> is -1, <s> is assumed to be null-terminated; otherwise, + // <len> indicates the number of bytes to insert. If <s> is a null pointer, + // uninitialized bytes are inserted and <len> must not be -1. A pointer to + // the inserted substring is returned for convenience. + char * insert(int pos, const char * s, int len = -1); + + // Removes <len> bytes at the given position. + void remove(int pos, int len); + + // Collapses any unused space preceding this string. + // Judicious use can combat memory fragmentation. + // Returns a move reference to allow e.g. "return str.settle();" + StringBuf && settle(); + + int len() const { return m_len; } + + operator char *() { return m_data; } + + // deprecated, use assignment + void steal(StringBuf && other) __attribute__((deprecated)); + // deprecated, use insert() + void combine(StringBuf && other) __attribute__((deprecated)); + +private: + StringStack * stack; + char * m_data; + int m_len; +}; + +#endif // LIBAUDCORE_OBJECTS_H diff --git a/src/libaudcore/output.cc b/src/libaudcore/output.cc new file mode 100644 index 0000000..53931de --- /dev/null +++ b/src/libaudcore/output.cc @@ -0,0 +1,842 @@ +/* + * output.c + * Copyright 2009-2015 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "output.h" + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> + +#include "equalizer.h" +#include "hook.h" +#include "i18n.h" +#include "interface.h" +#include "internal.h" +#include "plugin.h" +#include "plugins.h" +#include "runtime.h" +#include "threads.h" + +/* With Audacious 3.7, there is some support for secondary output plugins. + * Notes and limitations: + * - Only one secondary output can be in use at a time. + * - A reduced API is used, consisting of only open_audio(), close_audio(), and + * write_audio(). + * - The primary and secondary outputs are run from the same thread, with + * timing controlled by the primary's period_wait(). To avoid dropouts in + * the primary output, the secondary's write_audio() must be able to process + * audio faster than realtime. + * - The secondary's write_audio() is called in a tight loop until it has + * caught up to the primary, and should never return a zero byte count. */ + +/* Locking in this module is complicated by the fact that some of the + * output plugin functions (specifically period_wait() and drain()) are + * blocking calls. Various other functions are designed to be called + * in parallel with period_wait() and drain(). + * + * A two-mutex scheme is used to ensure that safe operations are allowed + * while a blocking call is in progress, and unsafe operations are + * prevented. The "major" mutex is locked before an unsafe operations; + * only the "minor" mutex is locked before a safe one. The "minor" mutex + * protects all changes to state data. + * + * The thread performing a blocking call (i.e. the input thread) must + * perform the following sequence: + * + * 1. Lock the major mutex + * 2. Lock the minor mutex + * 3. Check whether state data is correct for the call + * 4. Unlock the minor mutex + * 5. Call the blocking function + * 6. Unlock the major mutex + * + * The following classes attempt to enforce some of the rules regarding + * locking and state data. */ + +/* locks held for a "safe" operation */ +struct SafeLock +{ + aud::mutex::holder minor; +}; + +/* locks held for an "unsafe" operation */ +struct UnsafeLock : SafeLock +{ + aud::mutex::holder major; +}; + +class OutputState +{ +public: + bool input() const { return (m_flags & INPUT); } + bool output() const { return (m_flags & OUTPUT); } + bool secondary() const { return (m_flags & SECONDARY); } + bool paused() const { return (m_flags & PAUSED); } + bool flushed() const { return (m_flags & FLUSHED); } + bool resetting() const { return (m_flags & RESETTING); } + + SafeLock lock_safe() { return {mutex_minor.take()}; } + + UnsafeLock lock_unsafe() + { + UnsafeLock lock; + lock.major = mutex_major.take(); + lock.minor = mutex_minor.take(); + return lock; + } + + /* safe state changes */ + void set_secondary(SafeLock &, bool on) { set_flag(SECONDARY, on); } + void set_paused(SafeLock &, bool on) { set_flag(PAUSED, on); } + void set_flushed(SafeLock &, bool on) { set_flag(FLUSHED, on); } + void set_resetting(SafeLock &, bool on) { set_flag(RESETTING, on); } + + /* unsafe state changes */ + void set_input(UnsafeLock &, bool on) { set_flag(INPUT, on); } + void set_output(UnsafeLock &, bool on) { set_flag(OUTPUT, on); } + + void await_change(SafeLock & lock) { cond.wait(lock.minor); } + +private: + static constexpr int INPUT = (1 << 0); /* input plugin connected */ + static constexpr int OUTPUT = + (1 << 1); /* primary output plugin connected */ + static constexpr int SECONDARY = + (1 << 2); /* secondary output plugin connected */ + static constexpr int PAUSED = (1 << 3); /* paused */ + static constexpr int FLUSHED = + (1 << 4); /* flushed, writes ignored until resume */ + static constexpr int RESETTING = (1 << 5); /* resetting output system */ + + int m_flags = 0; + + aud::mutex mutex_major; + aud::mutex mutex_minor; + + aud::condvar cond; + + void set_flag(int flag, bool on) + { + m_flags = on ? (m_flags | flag) : (m_flags & ~flag); + /* wake any thread waiting for a state change */ + cond.notify_all(); + } +}; + +static OutputState state; + +static OutputPlugin * cop; /* current (primary) output plugin */ +static OutputPlugin * sop; /* secondary output plugin */ + +static OutputStream record_stream; + +static int seek_time; +static String in_filename; +static Tuple in_tuple; +static int in_format, in_channels, in_rate; +static int effect_channels, effect_rate; +static int sec_channels, sec_rate; +static int out_format, out_channels, out_rate; +static int out_bytes_per_sec, out_bytes_held; +static int64_t in_frames, out_bytes_written; +static ReplayGainInfo gain_info; +static bool gain_info_valid; + +static Index<float> buffer1; +static Index<char> buffer2; + +static inline int get_format(bool & automatic) +{ + automatic = false; + + switch (aud_get_int("output_bit_depth")) + { + case 16: + return FMT_S16_NE; + case 24: + return FMT_S24_3NE; + case 32: + return FMT_S32_NE; + + // return FMT_FLOAT for "auto" as well + case -1: + automatic = true; + default: + return FMT_FLOAT; + } +} + +static void setup_effects(SafeLock &) +{ + assert(state.input()); + + effect_channels = in_channels; + effect_rate = in_rate; + + effect_start(effect_channels, effect_rate); + eq_set_format(effect_channels, effect_rate); +} + +static void cleanup_output(UnsafeLock & lock) +{ + if (!state.output()) + return; + + // avoid locking up if the input thread reaches close_audio() while + // paused (unlikely but possible with perfect timing) + if (out_bytes_written && !state.paused()) + { + lock.minor.unlock(); + cop->drain(); + lock.minor.lock(); + } + + state.set_output(lock, false); + + buffer1.clear(); + buffer2.clear(); + + cop->close_audio(); + vis_runner_start_stop(false, false); +} + +static void cleanup_secondary(SafeLock & lock) +{ + if (!state.secondary()) + return; + + state.set_secondary(lock, false); + sop->close_audio(); +} + +static void apply_pause(SafeLock & lock, bool pause, bool new_output = false) +{ + if (state.output()) + { + // assume output plugin is unpaused after open_audio() + if (pause != (new_output ? false : state.paused())) + cop->pause(pause); + + vis_runner_start_stop(true, pause); + } + + state.set_paused(lock, pause); +} + +static bool open_audio_with_info(OutputPlugin * op, const char * filename, + const Tuple & tuple, int format, int rate, + int chans, String & error) +{ + op->set_info(filename, tuple); + return op->open_audio(format, rate, chans, error); +} + +static void setup_output(UnsafeLock & lock, bool new_input, bool pause) +{ + assert(state.input()); + + if (!cop) + return; + + bool automatic; + int format = get_format(automatic); + + if (state.output() && effect_channels == out_channels && + effect_rate == out_rate && !(new_input && cop->force_reopen)) + { + AUDINFO("Reuse output, %d channels, %d Hz.\n", effect_channels, + effect_rate); + apply_pause(lock, pause); + return; + } + + AUDINFO("Setup output, format %d, %d channels, %d Hz.\n", format, + effect_channels, effect_rate); + + cleanup_output(lock); + + String error; + while (!open_audio_with_info(cop, in_filename, in_tuple, format, + effect_rate, effect_channels, error)) + { + if (automatic && format == FMT_FLOAT) + format = FMT_S32_NE; + else if (automatic && format == FMT_S32_NE) + format = FMT_S16_NE; + else if (format == FMT_S24_3NE) + format = + FMT_S24_NE; /* some output plugins support only padded 24-bit */ + else + { + aud_ui_show_error(error ? (const char *)error + : _("Error opening output stream")); + return; + } + + AUDINFO("Falling back to format %d.\n", format); + } + + state.set_output(lock, true); + + out_format = format; + out_channels = effect_channels; + out_rate = effect_rate; + + out_bytes_per_sec = FMT_SIZEOF(format) * out_channels * out_rate; + out_bytes_held = 0; + out_bytes_written = 0; + + apply_pause(lock, pause, true); +} + +static void setup_secondary(SafeLock & lock, bool new_input) +{ + assert(state.input()); + + if (!sop) + return; + + int rate, channels; + record_stream = (OutputStream)aud_get_int("record_stream"); + + if (record_stream < OutputStream::AfterEffects) + { + rate = in_rate; + channels = in_channels; + } + else + { + rate = effect_rate; + channels = effect_channels; + } + + if (state.secondary() && channels == sec_channels && rate == sec_rate && + !(new_input && sop->force_reopen)) + return; + + cleanup_secondary(lock); + + String error; + if (!open_audio_with_info(sop, in_filename, in_tuple, FMT_FLOAT, rate, + channels, error)) + { + aud_ui_show_error(error ? (const char *)error + : _("Error recording output stream")); + return; + } + + state.set_secondary(lock, true); + + sec_channels = channels; + sec_rate = rate; +} + +static void flush_output(SafeLock &) +{ + assert(state.output()); + + out_bytes_held = 0; + out_bytes_written = 0; + + cop->flush(); + vis_runner_flush(); +} + +static void apply_replay_gain(SafeLock &, Index<float> & data) +{ + if (!aud_get_bool("enable_replay_gain")) + return; + + float factor = powf(10, aud_get_double("replay_gain_preamp") / 20); + + if (gain_info_valid) + { + float peak; + + auto mode = (ReplayGainMode)aud_get_int("replay_gain_mode"); + if ((mode == ReplayGainMode::Album) || + (mode == ReplayGainMode::Automatic && + (!aud_get_bool("shuffle") || aud_get_bool("album_shuffle")))) + { + factor *= powf(10, gain_info.album_gain / 20); + peak = gain_info.album_peak; + } + else + { + factor *= powf(10, gain_info.track_gain / 20); + peak = gain_info.track_peak; + } + + if (aud_get_bool("enable_clipping_prevention") && peak * factor > 1) + factor = 1 / peak; + } + else + factor *= powf(10, aud_get_double("default_gain") / 20); + + if (factor < 0.99 || factor > 1.01) + audio_amplify(data.begin(), 1, data.len(), &factor); +} + +static void write_secondary(SafeLock &, const Index<float> & data) +{ + assert(state.secondary()); + + auto begin = (const char *)data.begin(); + auto end = (const char *)data.end(); + + while (begin < end) + begin += sop->write_audio(begin, end - begin); +} + +static void write_output(UnsafeLock & lock, Index<float> & data) +{ + assert(state.output()); + + if (!data.len()) + return; + + if (state.secondary() && record_stream == OutputStream::AfterEffects) + write_secondary(lock, data); + + int out_time = + aud::rescale<int64_t>(out_bytes_written, out_bytes_per_sec, 1000); + vis_runner_pass_audio(out_time, data, out_channels, out_rate); + + eq_filter(data.begin(), data.len()); + + if (state.secondary() && record_stream == OutputStream::AfterEqualizer) + write_secondary(lock, data); + + if (aud_get_bool("software_volume_control")) + { + StereoVolume v = {aud_get_int("sw_volume_left"), + aud_get_int("sw_volume_right")}; + audio_amplify(data.begin(), out_channels, data.len() / out_channels, v); + } + + if (aud_get_bool("soft_clipping")) + audio_soft_clip(data.begin(), data.len()); + + const void * out_data = data.begin(); + + if (out_format != FMT_FLOAT) + { + buffer2.resize(FMT_SIZEOF(out_format) * data.len()); + audio_to_int(data.begin(), buffer2.begin(), out_format, data.len()); + out_data = buffer2.begin(); + } + + out_bytes_held = FMT_SIZEOF(out_format) * data.len(); + + while (out_bytes_held && !state.resetting()) + { + if (state.paused()) + { + // avoid locking up if the input thread reaches close_audio() while + // paused (unlikely but possible with perfect timing) + if (!state.input()) + break; + + state.await_change(lock); + continue; + } + + int written = cop->write_audio(out_data, out_bytes_held); + + out_data = (const char *)out_data + written; + out_bytes_held -= written; + out_bytes_written += written; + + if (!out_bytes_held) + break; + + lock.minor.unlock(); + cop->period_wait(); + lock.minor.lock(); + } +} + +static bool process_audio(UnsafeLock & lock, const void * data, int size, + int stop_time) +{ + assert(state.input() && state.output()); + + int samples = size / FMT_SIZEOF(in_format); + bool stopped = false; + + if (stop_time != -1) + { + int64_t frames_left = + aud::rescale<int64_t>(stop_time - seek_time, 1000, in_rate) - + in_frames; + int64_t samples_left = in_channels * aud::max((int64_t)0, frames_left); + + if (samples >= samples_left) + { + samples = samples_left; + stopped = true; + } + } + + in_frames += samples / in_channels; + + buffer1.resize(samples); + + if (in_format == FMT_FLOAT) + memcpy(buffer1.begin(), data, sizeof(float) * samples); + else + audio_from_int(data, in_format, buffer1.begin(), samples); + + if (state.secondary() && record_stream == OutputStream::AsDecoded) + write_secondary(lock, buffer1); + + apply_replay_gain(lock, buffer1); + + if (state.secondary() && record_stream == OutputStream::AfterReplayGain) + write_secondary(lock, buffer1); + + write_output(lock, effect_process(buffer1)); + + return !stopped; +} + +static void finish_effects(UnsafeLock & lock, bool end_of_playlist) +{ + assert(state.output()); + + buffer1.resize(0); + write_output(lock, effect_finish(buffer1, end_of_playlist)); +} + +bool output_open_audio(const String & filename, const Tuple & tuple, int format, + int rate, int channels, int start_time, bool pause) +{ + /* prevent division by zero */ + if (rate < 1 || channels < 1 || channels > AUD_MAX_CHANNELS) + return false; + + auto lock = state.lock_unsafe(); + + state.set_input(lock, true); + state.set_flushed(lock, false); + + seek_time = start_time; + gain_info_valid = false; + + in_filename = filename; + in_tuple = tuple.ref(); + in_format = format; + in_channels = channels; + in_rate = rate; + in_frames = 0; + + setup_effects(lock); + setup_output(lock, true, pause); + + if (aud_get_bool("record")) + setup_secondary(lock, true); + + return true; +} + +void output_set_tuple(const Tuple & tuple) +{ + auto lock = state.lock_safe(); + + if (state.input()) + in_tuple = tuple.ref(); +} + +void output_set_replay_gain(const ReplayGainInfo & info) +{ + auto lock = state.lock_safe(); + + if (state.input()) + { + gain_info = info; + gain_info_valid = true; + + AUDINFO("Replay Gain info:\n"); + AUDINFO(" album gain: %f dB\n", info.album_gain); + AUDINFO(" album peak: %f\n", info.album_peak); + AUDINFO(" track gain: %f dB\n", info.track_gain); + AUDINFO(" track peak: %f\n", info.track_peak); + } +} + +/* returns false if stop_time is reached */ +bool output_write_audio(const void * data, int size, int stop_time) +{ + while (1) + { + auto lock = state.lock_unsafe(); + if (!state.input() || state.flushed()) + return false; + + if (state.output() && !state.resetting()) + return process_audio(lock, data, size, stop_time); + + lock.major.unlock(); + state.await_change(lock); + } +} + +void output_flush(int time, bool force) +{ + auto lock = state.lock_safe(); + + if (state.input() || state.output()) + { + // allow effect plugins to prevent the flush, but + // always flush if paused to prevent locking up + bool flush = effect_flush(state.paused() || force); + if (flush && state.output()) + flush_output(lock); + } + + if (state.input()) + { + state.set_flushed(lock, true); + seek_time = time; + in_frames = 0; + } +} + +void output_resume() +{ + auto lock = state.lock_safe(); + + if (state.input()) + state.set_flushed(lock, false); +} + +void output_pause(bool pause) +{ + auto lock = state.lock_safe(); + + if (state.input()) + apply_pause(lock, pause); +} + +int output_get_time() +{ + auto lock = state.lock_safe(); + int time = 0, delay = 0; + + if (state.input()) + { + if (state.output()) + { + delay = cop->get_delay(); + delay += + aud::rescale<int64_t>(out_bytes_held, out_bytes_per_sec, 1000); + } + + delay = effect_adjust_delay(delay); + time = aud::rescale<int64_t>(in_frames, in_rate, 1000); + time = seek_time + aud::max(time - delay, 0); + } + + return time; +} + +int output_get_raw_time() +{ + auto lock = state.lock_safe(); + int time = 0; + + if (state.output()) + { + time = + aud::rescale<int64_t>(out_bytes_written, out_bytes_per_sec, 1000); + time = aud::max(time - cop->get_delay(), 0); + } + + return time; +} + +void output_close_audio() +{ + auto lock = state.lock_unsafe(); + + if (state.input()) + { + state.set_input(lock, false); + in_filename = String(); + in_tuple = Tuple(); + + if (state.output()) + finish_effects(lock, false); /* first time for end of song */ + } +} + +void output_drain() +{ + auto lock = state.lock_unsafe(); + + if (!state.input()) + { + if (state.output()) + finish_effects(lock, true); /* second time for end of playlist */ + + cleanup_output(lock); + cleanup_secondary(lock); + } +} + +static void output_reset(OutputReset type, OutputPlugin * op) +{ + auto lock1 = state.lock_safe(); + + state.set_resetting(lock1, true); + + if (state.output()) + flush_output(lock1); + + lock1.minor.unlock(); + auto lock2 = state.lock_unsafe(); + + if (type != OutputReset::EffectsOnly) + cleanup_output(lock2); + + /* this does not reset the secondary plugin */ + if (type == OutputReset::ResetPlugin) + { + if (cop) + cop->cleanup(); + + if (op) + { + /* secondary plugin may become primary */ + if (op == sop) + { + cleanup_secondary(lock2); + sop = nullptr; + } + else if (!op->init()) + op = nullptr; + } + + cop = op; + } + + if (state.input()) + { + if (type == OutputReset::EffectsOnly) + setup_effects(lock2); + + setup_output(lock2, false, state.paused()); + + if (aud_get_bool("record")) + setup_secondary(lock2, false); + } + + state.set_resetting(lock2, false); +} + +EXPORT void aud_output_reset(OutputReset type) { output_reset(type, cop); } + +EXPORT StereoVolume aud_drct_get_volume() +{ + auto lock = state.lock_safe(); + StereoVolume volume = {0, 0}; + + if (aud_get_bool("software_volume_control")) + volume = {aud_get_int("sw_volume_left"), + aud_get_int("sw_volume_right")}; + else if (cop) + volume = cop->get_volume(); + + return volume; +} + +EXPORT void aud_drct_set_volume(StereoVolume volume) +{ + auto lock = state.lock_safe(); + + volume.left = aud::clamp(volume.left, 0, 100); + volume.right = aud::clamp(volume.right, 0, 100); + + if (aud_get_bool("software_volume_control")) + { + aud_set_int("sw_volume_left", volume.left); + aud_set_int("sw_volume_right", volume.right); + } + else if (cop) + cop->set_volume(volume); +} + +PluginHandle * output_plugin_get_current() +{ + return cop ? aud_plugin_by_header(cop) : nullptr; +} + +PluginHandle * output_plugin_get_secondary() +{ + return sop ? aud_plugin_by_header(sop) : nullptr; +} + +bool output_plugin_set_current(PluginHandle * plugin) +{ + output_reset(OutputReset::ResetPlugin, + plugin ? (OutputPlugin *)aud_plugin_get_header(plugin) + : nullptr); + return (!plugin || cop); +} + +bool output_plugin_set_secondary(PluginHandle * plugin) +{ + auto lock = state.lock_safe(); + + cleanup_secondary(lock); + if (sop) + sop->cleanup(); + + sop = plugin ? (OutputPlugin *)aud_plugin_get_header(plugin) : nullptr; + if (sop && !sop->init()) + sop = nullptr; + + if (state.input() && aud_get_bool("record")) + setup_secondary(lock, false); + + return (!plugin || sop); +} + +static void record_settings_changed(void *, void *) +{ + auto lock = state.lock_safe(); + + if (state.input() && aud_get_bool("record")) + setup_secondary(lock, false); + else + cleanup_secondary(lock); +} + +void output_init() +{ + hook_associate("set record", record_settings_changed, nullptr); + hook_associate("set record_stream", record_settings_changed, nullptr); +} + +void output_cleanup() +{ + hook_dissociate("set record", record_settings_changed); + hook_dissociate("set record_stream", record_settings_changed); +} diff --git a/src/libaudcore/output.h b/src/libaudcore/output.h new file mode 100644 index 0000000..7f6e06f --- /dev/null +++ b/src/libaudcore/output.h @@ -0,0 +1,51 @@ +/* + * output.h + * Copyright 2010-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_OUTPUT_H +#define LIBAUDCORE_OUTPUT_H + +#include <libaudcore/audio.h> +#include <libaudcore/objects.h> + +class PluginHandle; +class Tuple; + +void output_init(); +void output_cleanup(); + +bool output_open_audio(const String & filename, const Tuple & tuple, int format, + int rate, int channels, int start_time, bool pause); +void output_set_tuple(const Tuple & tuple); +void output_set_replay_gain(const ReplayGainInfo & info); +bool output_write_audio(const void * data, int size, int stop_time); +void output_flush(int time, bool force = false); +void output_resume(); +void output_pause(bool pause); + +int output_get_time(); +int output_get_raw_time(); +void output_close_audio(); +void output_drain(); + +PluginHandle * output_plugin_get_current(); +PluginHandle * output_plugin_get_secondary(); +bool output_plugin_set_current(PluginHandle * plugin); +bool output_plugin_set_secondary(PluginHandle * plugin); + +#endif diff --git a/src/libaudcore/parse.cc b/src/libaudcore/parse.cc new file mode 100644 index 0000000..ab6c5f3 --- /dev/null +++ b/src/libaudcore/parse.cc @@ -0,0 +1,50 @@ +/* + * parse.cc + * Copyright 2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "parse.h" +#include <string.h> + +void TextParser::next() +{ + m_val = nullptr; + + if (!fgets(m_key, sizeof m_key, m_file)) + return; + + char * space = strchr(m_key, ' '); + if (!space) + return; + + *space = 0; + m_val = space + 1; + + char * newline = strchr(m_val, '\n'); + if (newline) + *newline = 0; +} + +bool TextParser::get_int(const char * key, int & val) const +{ + return (m_val && !strcmp(m_key, key) && sscanf(m_val, "%d", &val) == 1); +} + +String TextParser::get_str(const char * key) const +{ + return (m_val && !strcmp(m_key, key)) ? String(m_val) : String(); +} diff --git a/src/libaudcore/parse.h b/src/libaudcore/parse.h new file mode 100644 index 0000000..c1f96b3 --- /dev/null +++ b/src/libaudcore/parse.h @@ -0,0 +1,45 @@ +/* + * parse.h + * Copyright 2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_PARSE_H +#define LIBAUDCORE_PARSE_H + +#include "objects.h" +#include <stdio.h> + +// simplistic key-value file parser +// used for playlist-state and plugin-registry files +class TextParser +{ +public: + TextParser(FILE * file) : m_file(file) { next(); } + + void next(); + bool eof() const { return !m_val; } + + bool get_int(const char * key, int & val) const; + String get_str(const char * key) const; + +private: + FILE * m_file; + char * m_val; + char m_key[512]; +}; + +#endif // LIBAUDCORE_PARSE_H diff --git a/src/libaudcore/playback.cc b/src/libaudcore/playback.cc new file mode 100644 index 0000000..321db52 --- /dev/null +++ b/src/libaudcore/playback.cc @@ -0,0 +1,717 @@ +/* + * playback.cc + * Copyright 2009-2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +/* + * Since Audacious 3.6, the playback thread is completely asynchronous; that is, + * the main thread never blocks waiting for the playback thread to process a + * play(), seek(), or stop() command. As a result, the playback thread can lag + * behind the main/playlist thread, and the "current" song from the perspective + * of the playback thread may not be the same as the "current" song from the + * perspective of the main/playlist thread. Therefore, some care is necessary + * to ensure that information generated in the playback thread is not applied to + * the wrong song. To this end, separate serial numbers are maintained by each + * thread and compared when information crosses thread boundaries; if the serial + * numbers do not match, the information is generally discarded. + * + * Note that this file and playlist.cc each have their own mutex. The one in + * playlist.cc is conceptually the "outer" mutex and must be locked first (in + * situations where both need to be locked) in order to avoid deadlock. + */ + +#include "drct.h" +#include "internal.h" + +#include <assert.h> + +#include "audstrings.h" +#include "hook.h" +#include "i18n.h" +#include "interface.h" +#include "mainloop.h" +#include "output.h" +#include "playlist-internal.h" +#include "plugin.h" +#include "plugins-internal.h" +#include "plugins.h" +#include "runtime.h" +#include "threads.h" + +struct PlaybackState +{ + bool playing = false; + bool thread_running = false; + int control_serial = 0; + int playback_serial = 0; +}; + +struct PlaybackControl +{ + bool paused = false; + int seek = -1; + int repeat_a = -1; + int repeat_b = -1; +}; + +struct PlaybackInfo +{ + // set by playback_set_info + int entry = -1; + Tuple tuple; + String title; + + // set by playback thread + String filename; + int length = -1; + int time_offset = 0; + int stop_time = -1; + + ReplayGainInfo gain{}; + bool gain_valid = false; + + int bitrate = 0; + int samplerate = 0; + int channels = 0; + + bool ready = false; + bool ended = false; + bool error = false; + String error_s; +}; + +static aud::mutex mutex; +static aud::condvar cond; + +static PlaybackState pb_state; +static PlaybackControl pb_control; +static PlaybackInfo pb_info; + +static QueuedFunc end_queue; +static bool song_finished = false; +static int failed_entries = 0; + +// check that the playback thread is not lagging +static bool in_sync(aud::mutex::holder &) +{ + return pb_state.playing && + pb_state.control_serial == pb_state.playback_serial; +} + +// check that the playback thread is not lagging and playback is "ready" +static bool is_ready(aud::mutex::holder & mh) +{ + return in_sync(mh) && pb_info.ready; +} + +// called by playback_entry_set_tuple() to ensure that the tuple still applies +// to the current song from the perspective of the main/playlist thread; the +// check is necessary because playback_entry_set_tuple() is itself called from +// the playback thread +bool playback_check_serial(int serial) +{ + auto mh = mutex.take(); + return pb_state.playing && pb_state.control_serial == serial; +} + +// called from the playlist to update the tuple for the current song +void playback_set_info(int entry, Tuple && tuple) +{ + // do nothing if the playback thread is lagging behind; + // in that case, playback_set_info() will get called again anyway + auto mh = mutex.take(); + if (!in_sync(mh)) + return; + + if (tuple.valid() && tuple != pb_info.tuple) + { + pb_info.tuple = std::move(tuple); + + // don't call "tuple change" before "playback ready" + if (is_ready(mh)) + { + event_queue("tuple change", nullptr); + output_set_tuple(pb_info.tuple); + } + } + + String title = pb_info.tuple.get_str(Tuple::FormattedTitle); + if (entry != pb_info.entry || title != pb_info.title) + { + pb_info.entry = entry; + pb_info.title = title; + + // don't call "title change" before "playback ready" + if (is_ready(mh)) + event_queue("title change", nullptr); + } +} + +// cleanup common to both playback_play() and playback_stop() +static void playback_cleanup(aud::mutex::holder &) +{ + pb_state.playing = false; + pb_control = PlaybackControl(); + + // miscellaneous cleanup + end_queue.stop(); + song_finished = false; + + event_queue_cancel("playback ready"); + event_queue_cancel("playback pause"); + event_queue_cancel("playback unpause"); + event_queue_cancel("playback seek"); + event_queue_cancel("info change"); + event_queue_cancel("title change"); + event_queue_cancel("tuple change"); + + aud_set_bool("stop_after_current_song", false); +} + +// main thread: stops playback when no more songs are to be played +void playback_stop(bool exiting) +{ + if (!pb_state.playing && !exiting) + return; + + auto mh = mutex.take(); + + // discard audio buffer on a user-initiated stop + if (!song_finished || exiting) + output_flush(0, exiting); + + if (pb_state.playing) + playback_cleanup(mh); + + if (pb_state.thread_running) + { + // signal playback thread to drain audio buffer + pb_state.control_serial++; + cond.notify_all(); + + // wait for playback thread to finish if exiting + while (exiting && pb_state.thread_running) + cond.wait(mh); + } + + // miscellaneous cleanup + failed_entries = 0; +} + +// called from top-level event loop after playback finishes +static void end_cb(void *) +{ + song_finished = true; + hook_call("playback end", nullptr); + + PlaylistEx playlist = Playlist::playing_playlist(); + + auto do_stop = [playlist]() { + aud_drct_stop(); + playlist.set_position(playlist.get_position()); + }; + + auto do_next = [playlist]() { + if (!playlist.next_song(aud_get_bool("repeat"))) + { + playlist.set_position(-1); + hook_call("playlist end reached", nullptr); + } + }; + + if (aud_get_bool("no_playlist_advance")) + { + // we assume here that repeat is not enabled; + // single-song repeats are handled in run_playback() + do_stop(); + } + else if (aud_get_bool("stop_after_current_song")) + { + do_stop(); + do_next(); + } + else + { + // if 10 songs in a row have failed, or if the entire playlist + // (for playlists less than 10 songs) has failed, stop trying + if (failed_entries < aud::min(playlist.n_entries(), 10)) + do_next(); + else + do_stop(); + } +} + +// helper, can be called from either main or playback thread +static void request_seek(aud::mutex::holder & mh, int time) +{ + // set up "seek" command whether ready or not; + // if not ready, it will take effect upon open_audio() + pb_control.seek = aud::max(0, time); + + // trigger seek immediately if ready + if (is_ready(mh) && pb_info.length > 0) + { + output_flush(aud::clamp(time, 0, pb_info.length)); + event_queue("playback seek", nullptr); + } +} + +// playback thread helper +static bool setup_playback(const DecodeInfo & dec) +{ + auto mh = mutex.take(); + if (!in_sync(mh)) + return false; + + // for a cuesheet entry, determine the source filename + pb_info.filename = pb_info.tuple.get_str(Tuple::AudioFile); + if (!pb_info.filename) + pb_info.filename = std::move(dec.filename); + + // check that we have all the necessary data + if (!pb_info.filename || !pb_info.tuple.valid() || !dec.ip || + (!dec.ip->input_info.keys[InputKey::Scheme] && !dec.file)) + { + pb_info.error = true; + pb_info.error_s = std::move(dec.error); + return false; + } + + // get various other bits of info from the tuple + pb_info.length = pb_info.tuple.get_int(Tuple::Length); + pb_info.time_offset = aud::max(0, pb_info.tuple.get_int(Tuple::StartTime)); + pb_info.stop_time = aud::max(-1, pb_info.tuple.get_int(Tuple::EndTime) - + pb_info.time_offset); + pb_info.gain = pb_info.tuple.get_replay_gain(); + pb_info.gain_valid = pb_info.tuple.has_replay_gain(); + + // force initial seek if we are playing a segmented track + if (pb_info.time_offset > 0 && pb_control.seek < 0) + pb_control.seek = 0; + + return true; +} + +// playback thread helper +static bool check_playback_repeat() +{ + auto mh = mutex.take(); + if (!is_ready(mh)) + return false; + + // check whether we need to repeat + if (pb_control.repeat_a >= 0 || + (aud_get_bool("repeat") && aud_get_bool("no_playlist_advance"))) + { + // treat the repeat as a seek (takes effect at open_audio()) + pb_control.seek = pb_control.repeat_a; + + // force initial seek if we are playing a segmented track + if (pb_info.time_offset > 0 && pb_control.seek < 0) + pb_control.seek = 0; + + event_queue("playback seek", nullptr); + pb_info.ended = false; + return true; + } + + pb_info.ended = true; + return false; +} + +// playback thread helper +static void run_playback() +{ + // due to mutex ordering, we cannot call into the playlist while locked + DecodeInfo dec = playback_entry_read(pb_state.playback_serial); + + if (!setup_playback(dec)) + return; + + while (1) + { + // hand off control to input plugin + if (!dec.ip->play(pb_info.filename, dec.file)) + pb_info.error = true; + + // close audio (no-op if it wasn't opened) + output_close_audio(); + + if (pb_info.error || pb_info.length <= 0) + break; + + if (!check_playback_repeat()) + break; + + // rewind file pointer before repeating + if (!open_input_file(pb_info.filename, "r", dec.ip, dec.file, + &pb_info.error_s)) + { + pb_info.error = true; + break; + } + } +} + +// playback thread helper +static void finish_playback(aud::mutex::holder &) +{ + // record any playback error that occurred + if (pb_info.error) + { + failed_entries++; + + if (pb_info.error_s) + aud_ui_show_error(str_printf(_("Error playing %s:\n%s"), + (const char *)pb_info.filename, + (const char *)pb_info.error_s)); + else + AUDERR("Playback finished with error.\n"); + } + else + failed_entries = 0; + + // queue up function to start next song (or perform cleanup) + end_queue.queue(end_cb, nullptr); +} + +// playback thread +static void playback_thread() +{ + auto mh = mutex.take(); + + while (1) + { + // wait for a command + while (pb_state.control_serial == pb_state.playback_serial) + cond.wait(mh); + + // fetch the command (either "play" or "drain") + bool play = pb_state.playing; + + // update playback thread serial number + pb_state.playback_serial = pb_state.control_serial; + + mh.unlock(); + + if (play) + run_playback(); + else + output_drain(); + + mh.lock(); + + if (play) + { + // don't report errors or queue next song if another command is + // pending + if (in_sync(mh)) + finish_playback(mh); + + pb_info = PlaybackInfo(); + } + else + { + // quit if we did not receive a new command after draining + if (pb_state.control_serial == pb_state.playback_serial) + break; + } + } + + // signal the main thread that we are quitting + pb_state.thread_running = false; + cond.notify_all(); +} + +// main thread: starts playback of a new song +void playback_play(int seek_time, bool pause) +{ + auto mh = mutex.take(); + + // discard audio buffer unless progressing to the next song + if (!song_finished) + output_flush(0); + + if (pb_state.playing) + playback_cleanup(mh); + + // set up "play" command + pb_state.playing = true; + pb_state.control_serial++; + pb_control.paused = pause; + pb_control.seek = (seek_time > 0) ? seek_time : -1; + + // start playback thread (or signal it if it's already running) + if (pb_state.thread_running) + cond.notify_all(); + else + { + std::thread(playback_thread).detach(); + pb_state.thread_running = true; + } +} + +// main thread +EXPORT void aud_drct_pause() +{ + if (!pb_state.playing) + return; + + auto mh = mutex.take(); + + // set up "pause" command whether ready or not; + // if not ready, it will take effect upon open_audio() + bool pause = !pb_control.paused; + pb_control.paused = pause; + + // apply pause immediately if ready + if (is_ready(mh)) + output_pause(pause); + + event_queue(pause ? "playback pause" : "playback unpause", nullptr); +} + +// main thread +EXPORT void aud_drct_seek(int time) +{ + if (!pb_state.playing) + return; + + auto mh = mutex.take(); + request_seek(mh, time); +} + +EXPORT void InputPlugin::open_audio(int format, int rate, int channels) +{ + // don't open audio if playback thread is lagging + auto mh = mutex.take(); + if (!in_sync(mh)) + return; + + if (!output_open_audio(pb_info.filename, pb_info.tuple, format, rate, + channels, aud::max(0, pb_control.seek), + pb_control.paused)) + { + pb_info.error = true; + pb_info.error_s = String(_("Invalid audio format")); + return; + } + + if (pb_info.gain_valid) + output_set_replay_gain(pb_info.gain); + + pb_info.samplerate = rate; + pb_info.channels = channels; + + if (pb_info.ready) + event_queue("info change", nullptr); + else + event_queue("playback ready", nullptr); + + pb_info.ready = true; +} + +EXPORT void InputPlugin::set_replay_gain(const ReplayGainInfo & gain) +{ + auto mh = mutex.take(); + + pb_info.gain = gain; + pb_info.gain_valid = true; + + if (is_ready(mh)) + output_set_replay_gain(gain); +} + +EXPORT void InputPlugin::write_audio(const void * data, int length) +{ + auto mh = mutex.take(); + if (!in_sync(mh)) + return; + + // fetch A-B repeat settings + int a = pb_control.repeat_a; + int b = pb_control.repeat_b; + + mh.unlock(); + + // it's okay to call output_write_audio() even if we are no longer in sync, + // since it will return immediately if output_flush() has been called + int stop_time = (b >= 0) ? b : pb_info.stop_time; + if (output_write_audio(data, length, stop_time)) + return; + + mh.lock(); + + if (!in_sync(mh)) + return; + + // if we are still in sync, then one of the following happened: + // 1. output_flush() was called due to a seek request + // 2. we've reached repeat point B + // 3. we've reached the end of a segmented track + if (pb_control.seek < 0) + { + if (b >= 0) + request_seek(mh, a); + else + pb_info.ended = true; + } +} + +EXPORT Tuple InputPlugin::get_playback_tuple() +{ + auto mh = mutex.take(); + Tuple tuple = pb_info.tuple.ref(); + + // tuples passed to us from input plugins do not have fallback fields + // generated; for consistency, tuples passed back should not either + tuple.delete_fallbacks(); + return tuple; +} + +EXPORT void InputPlugin::set_playback_tuple(Tuple && tuple) +{ + // due to mutex ordering, we cannot call into the playlist while locked; + // instead, playback_entry_set_tuple() calls back into first + // playback_check_serial() and then eventually playback_set_info() + playback_entry_set_tuple(pb_state.playback_serial, std::move(tuple)); +} + +EXPORT void InputPlugin::set_stream_bitrate(int bitrate) +{ + auto mh = mutex.take(); + pb_info.bitrate = bitrate; + + if (is_ready(mh)) + event_queue("info change", nullptr); +} + +EXPORT bool InputPlugin::check_stop() +{ + auto mh = mutex.take(); + return !is_ready(mh) || pb_info.ended || pb_info.error; +} + +EXPORT int InputPlugin::check_seek() +{ + auto mh = mutex.take(); + int seek = -1; + + if (is_ready(mh) && pb_control.seek >= 0 && pb_info.length > 0) + { + seek = pb_info.time_offset + aud::min(pb_control.seek, pb_info.length); + pb_control.seek = -1; + output_resume(); + } + + return seek; +} + +// thread-safe +EXPORT bool aud_drct_get_playing() +{ + auto mh = mutex.take(); + return pb_state.playing; +} + +// thread-safe +EXPORT bool aud_drct_get_ready() +{ + auto mh = mutex.take(); + return is_ready(mh); +} + +// thread-safe +EXPORT bool aud_drct_get_paused() +{ + auto mh = mutex.take(); + return pb_control.paused; +} + +// thread-safe +EXPORT String aud_drct_get_title() +{ + auto mh = mutex.take(); + if (!is_ready(mh)) + return String(); + + StringBuf prefix = aud_get_bool("show_numbers_in_pl") + ? str_printf("%d. ", 1 + pb_info.entry) + : StringBuf(0); + + StringBuf time = + (pb_info.length > 0) ? str_format_time(pb_info.length) : StringBuf(); + StringBuf suffix = time ? str_concat({" (", time, ")"}) : StringBuf(0); + + return String(str_concat({prefix, pb_info.title, suffix})); +} + +// thread-safe +EXPORT Tuple aud_drct_get_tuple() +{ + auto mh = mutex.take(); + return is_ready(mh) ? pb_info.tuple.ref() : Tuple(); +} + +// thread-safe +EXPORT void aud_drct_get_info(int & bitrate, int & samplerate, int & channels) +{ + auto mh = mutex.take(); + bool ready = is_ready(mh); + + bitrate = ready ? pb_info.bitrate : 0; + samplerate = ready ? pb_info.samplerate : 0; + channels = ready ? pb_info.channels : 0; +} + +// thread-safe +EXPORT int aud_drct_get_time() +{ + auto mh = mutex.take(); + return is_ready(mh) ? output_get_time() : 0; +} + +// thread-safe +EXPORT int aud_drct_get_length() +{ + auto mh = mutex.take(); + return is_ready(mh) ? pb_info.length : -1; +} + +// main thread +EXPORT void aud_drct_set_ab_repeat(int a, int b) +{ + if (!pb_state.playing) + return; + + auto mh = mutex.take(); + + pb_control.repeat_a = a; + pb_control.repeat_b = b; + + if (b >= 0 && is_ready(mh) && output_get_time() >= b) + request_seek(mh, a); +} + +// thread-safe +EXPORT void aud_drct_get_ab_repeat(int & a, int & b) +{ + auto mh = mutex.take(); + + a = pb_control.repeat_a; + b = pb_control.repeat_b; +} diff --git a/src/libaudcore/playlist-cache.cc b/src/libaudcore/playlist-cache.cc new file mode 100644 index 0000000..1cf8035 --- /dev/null +++ b/src/libaudcore/playlist-cache.cc @@ -0,0 +1,79 @@ +/* + * playlist-cache.h + * Copyright 2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "mainloop.h" +#include "multihash.h" +#include "playlist-internal.h" +#include "threads.h" + +static SimpleHash<String, PlaylistAddItem> cache; +static aud::mutex mutex; +static QueuedFunc clear_timer; + +EXPORT void Playlist::cache_selected() const +{ + auto mh = mutex.take(); + int entries = n_entries(); + + for (int i = 0; i < entries; i++) + { + if (!entry_selected(i)) + continue; + + String filename = entry_filename(i); + Tuple tuple = entry_tuple(i, NoWait); + PluginHandle * decoder = entry_decoder(i, NoWait); + + if (tuple.valid() || decoder) + cache.add(filename, {filename, std::move(tuple), decoder}); + } + + clear_timer.queue(30000, playlist_cache_clear, nullptr); +} + +void playlist_cache_load(Index<PlaylistAddItem> & items) +{ + auto mh = mutex.take(); + + if (!cache.n_items()) + return; + + for (auto & item : items) + { + if (item.tuple.valid() && item.decoder) + continue; + + auto node = cache.lookup(item.filename); + if (!node) + continue; + + if (!item.tuple.valid() && node->tuple.valid()) + item.tuple = node->tuple.ref(); + if (!item.decoder && node->decoder) + item.decoder = node->decoder; + } +} + +void playlist_cache_clear(void *) +{ + auto mh = mutex.take(); + + cache.clear(); + clear_timer.stop(); +} diff --git a/src/libaudcore/playlist-data.cc b/src/libaudcore/playlist-data.cc new file mode 100644 index 0000000..923e6f1 --- /dev/null +++ b/src/libaudcore/playlist-data.cc @@ -0,0 +1,1245 @@ +/* + * playlist-data.cc + * Copyright 2017 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "playlist-data.h" + +#include <stdlib.h> +#include <string.h> + +#include "runtime.h" +#include "scanner.h" +#include "tuple-compiler.h" + +#define NO_POS \ + { \ + -1, false \ + } + +static TupleCompiler s_tuple_formatter; +static bool s_use_tuple_fallbacks = false; + +struct PlaylistEntry +{ + PlaylistEntry(PlaylistAddItem && item); + ~PlaylistEntry(); + + void format(); + void set_tuple(Tuple && new_tuple); + + String filename; + PluginHandle * decoder; + Tuple tuple; + String error; + int number; + int length; + int shuffle_num; + bool selected, queued; +}; + +void PlaylistEntry::format() +{ + tuple.delete_fallbacks(); + + if (s_use_tuple_fallbacks) + tuple.generate_fallbacks(); + else + tuple.generate_title(); + + s_tuple_formatter.format(tuple); +} + +void PlaylistEntry::set_tuple(Tuple && new_tuple) +{ + /* Since 3.8, cuesheet entries are handled differently. The entry filename + * points to the .cue file, and the path to the actual audio file is stored + * in the Tuple::AudioFile. If Tuple::AudioFile is not set, then assume + * that the playlist was created by an older version of Audacious, and + * revert to the former behavior (don't refresh this entry). */ + if (tuple.is_set(Tuple::StartTime) && !tuple.is_set(Tuple::AudioFile)) + return; + + error = String(); + + if (!new_tuple.valid()) + new_tuple.set_filename(filename); + + length = aud::max(0, new_tuple.get_int(Tuple::Length)); + tuple = std::move(new_tuple); + + format(); +} + +PlaylistEntry::PlaylistEntry(PlaylistAddItem && item) + : filename(item.filename), decoder(item.decoder), number(-1), length(0), + shuffle_num(0), selected(false), queued(false) +{ + set_tuple(std::move(item.tuple)); +} + +PlaylistEntry::~PlaylistEntry() { pl_signal_entry_deleted(this); } + +void PlaylistData::update_formatter() // static +{ + s_tuple_formatter.compile(aud_get_str("generic_title_format")); + s_use_tuple_fallbacks = aud_get_bool("metadata_fallbacks"); +} + +void PlaylistData::cleanup_formatter() // static +{ + s_tuple_formatter.reset(); +} + +void PlaylistData::delete_entry(PlaylistEntry * entry) // static +{ + delete entry; +} + +PlaylistData::PlaylistData(Playlist::ID * id, const char * title) + : modified(true), scan_status(NotScanning), title(title), resume_time(0), + m_id(id), m_position(nullptr), m_focus(nullptr), m_selected_count(0), + m_last_shuffle_num(0), m_total_length(0), m_selected_length(0), + m_last_update(), m_next_update(), m_position_changed(false) +{ +} + +PlaylistData::~PlaylistData() { pl_signal_playlist_deleted(m_id); } + +void PlaylistData::number_entries(int at, int length) +{ + for (int i = at; i < at + length; i++) + m_entries[i]->number = i; +} + +PlaylistEntry * PlaylistData::entry_at(int i) +{ + return (i >= 0 && i < m_entries.len()) ? m_entries[i].get() : nullptr; +} + +const PlaylistEntry * PlaylistData::entry_at(int i) const +{ + return (i >= 0 && i < m_entries.len()) ? m_entries[i].get() : nullptr; +} + +String PlaylistData::entry_filename(int i) const +{ + auto entry = entry_at(i); + return entry ? entry->filename : String(); +} + +PluginHandle * PlaylistData::entry_decoder(int i, String * error) const +{ + auto entry = entry_at(i); + if (error) + *error = entry ? entry->error : String(); + return entry ? entry->decoder : nullptr; +} + +Tuple PlaylistData::entry_tuple(int i, String * error) const +{ + auto entry = entry_at(i); + if (error) + *error = entry ? entry->error : String(); + return entry ? entry->tuple.ref() : Tuple(); +} + +static bool same_album(const Tuple & a, const Tuple & b) +{ + String album = a.get_str(Tuple::Album); + return (album && album == b.get_str(Tuple::Album)); +} + +void PlaylistData::set_entry_tuple(PlaylistEntry * entry, Tuple && tuple) +{ + m_total_length -= entry->length; + if (entry->selected) + m_selected_length -= entry->length; + + entry->set_tuple(std::move(tuple)); + + m_total_length += entry->length; + if (entry->selected) + m_selected_length += entry->length; +} + +void PlaylistData::queue_update(Playlist::UpdateLevel level, int at, int count, + int flags) +{ + if (m_next_update.level) + { + m_next_update.level = aud::max(m_next_update.level, level); + m_next_update.before = aud::min(m_next_update.before, at); + m_next_update.after = + aud::min(m_next_update.after, m_entries.len() - at - count); + } + else + { + m_next_update.level = level; + m_next_update.before = at; + m_next_update.after = m_entries.len() - at - count; + } + + if ((flags & QueueChanged)) + m_next_update.queue_changed = true; + + pl_signal_update_queued(m_id, level, flags); +} + +void PlaylistData::queue_position_change() +{ + m_position_changed = true; + pl_signal_position_changed(m_id); +} + +void PlaylistData::cancel_updates() +{ + m_last_update = Playlist::Update(); + m_next_update = Playlist::Update(); + m_position_changed = false; +} + +void PlaylistData::swap_updates(bool & position_changed) +{ + m_last_update = m_next_update; + m_next_update = Playlist::Update(); + position_changed = m_position_changed; + m_position_changed = false; +} + +void PlaylistData::insert_items(int at, Index<PlaylistAddItem> && items) +{ + int n_entries = m_entries.len(); + int n_items = items.len(); + + if (at < 0 || at > n_entries) + at = n_entries; + + m_entries.insert(at, n_items); + + int i = at; + for (auto & item : items) + { + auto entry = new PlaylistEntry(std::move(item)); + m_entries[i++].capture(entry); + m_total_length += entry->length; + } + + items.clear(); + + number_entries(at, n_entries + n_items - at); + queue_update(Playlist::Structure, at, n_items); +} + +void PlaylistData::remove_entries(int at, int number) +{ + int n_entries = m_entries.len(); + bool position_changed = false; + int update_flags = 0; + + if (at < 0 || at > n_entries) + at = n_entries; + if (number < 0 || number > n_entries - at) + number = n_entries - at; + + if (m_position && m_position->number >= at && + m_position->number < at + number) + { + change_position(NO_POS); + position_changed = true; + } + + if (m_focus && m_focus->number >= at && m_focus->number < at + number) + { + if (at + number < n_entries) + m_focus = m_entries[at + number].get(); + else if (at > 0) + m_focus = m_entries[at - 1].get(); + else + m_focus = nullptr; + } + + for (int i = 0; i < number; i++) + { + PlaylistEntry * entry = m_entries[at + i].get(); + + if (entry->queued) + { + m_queued.remove(m_queued.find(entry), 1); + update_flags |= QueueChanged; + } + + if (entry->selected) + { + m_selected_count--; + m_selected_length -= entry->length; + } + + m_total_length -= entry->length; + } + + m_entries.remove(at, number); + + number_entries(at, n_entries - at - number); + queue_update(Playlist::Structure, at, 0, update_flags); + + if (position_changed) + { + if (aud_get_bool("advance_on_delete")) + change_position_to_next(aud_get_bool("repeat"), at); + + queue_position_change(); + } +} + +int PlaylistData::position() const +{ + return m_position ? m_position->number : -1; +} + +int PlaylistData::focus() const { return m_focus ? m_focus->number : -1; } + +bool PlaylistData::entry_selected(int entry_num) const +{ + auto entry = entry_at(entry_num); + return entry ? entry->selected : false; +} + +int PlaylistData::n_selected(int at, int number) const +{ + int n_entries = m_entries.len(); + + if (at < 0 || at > n_entries) + at = n_entries; + if (number < 0 || number > n_entries - at) + number = n_entries - at; + + int n_selected = 0; + + if (at == 0 && number == n_entries) + n_selected = m_selected_count; + else + { + for (int i = 0; i < number; i++) + { + if (m_entries[at + i]->selected) + n_selected++; + } + } + + return n_selected; +} + +void PlaylistData::set_focus(int entry_num) +{ + auto new_focus = entry_at(entry_num); + if (new_focus == m_focus) + return; + + int first = m_entries.len(); + int last = -1; + + if (m_focus) + { + first = aud::min(first, m_focus->number); + last = aud::max(last, m_focus->number); + } + + m_focus = new_focus; + + if (m_focus) + { + first = aud::min(first, m_focus->number); + last = aud::max(last, m_focus->number); + } + + if (first <= last) + queue_update(Playlist::Selection, first, last + 1 - first); +} + +void PlaylistData::select_entry(int entry_num, bool selected) +{ + auto entry = entry_at(entry_num); + if (!entry || entry->selected == selected) + return; + + entry->selected = selected; + + if (selected) + { + m_selected_count++; + m_selected_length += entry->length; + } + else + { + m_selected_count--; + m_selected_length -= entry->length; + } + + queue_update(Playlist::Selection, entry_num, 1); +} + +void PlaylistData::select_all(bool selected) +{ + int n_entries = m_entries.len(); + int first = n_entries, last = 0; + + for (auto & entry : m_entries) + { + if (entry->selected != selected) + { + entry->selected = selected; + first = aud::min(first, entry->number); + last = entry->number; + } + } + + if (selected) + { + m_selected_count = n_entries; + m_selected_length = m_total_length; + } + else + { + m_selected_count = 0; + m_selected_length = 0; + } + + if (first < n_entries) + queue_update(Playlist::Selection, first, last + 1 - first); +} + +int PlaylistData::shift_entries(int entry_num, int distance) +{ + PlaylistEntry * entry = entry_at(entry_num); + if (!entry || !entry->selected || !distance) + return 0; + + int n_entries = m_entries.len(); + int shift = 0, center, top, bottom; + + if (distance < 0) + { + for (center = entry_num; center > 0 && shift > distance;) + { + if (!m_entries[--center]->selected) + shift--; + } + } + else + { + for (center = entry_num + 1; center < n_entries && shift < distance;) + { + if (!m_entries[center++]->selected) + shift++; + } + } + + top = bottom = center; + + for (int i = 0; i < top; i++) + { + if (m_entries[i]->selected) + top = i; + } + + for (int i = n_entries; i > bottom; i--) + { + if (m_entries[i - 1]->selected) + bottom = i; + } + + Index<EntryPtr> temp; + + for (int i = top; i < center; i++) + { + if (!m_entries[i]->selected) + temp.append(std::move(m_entries[i])); + } + + for (int i = top; i < bottom; i++) + { + if (m_entries[i] && m_entries[i]->selected) + temp.append(std::move(m_entries[i])); + } + + for (int i = center; i < bottom; i++) + { + if (m_entries[i] && !m_entries[i]->selected) + temp.append(std::move(m_entries[i])); + } + + m_entries.move_from(temp, 0, top, bottom - top, false, true); + + number_entries(top, bottom - top); + queue_update(Playlist::Structure, top, bottom - top); + + return shift; +} + +void PlaylistData::remove_selected() +{ + if (!m_selected_count) + return; + + int n_entries = m_entries.len(); + bool position_changed = false; + int update_flags = 0; + + if (m_position && m_position->selected) + { + change_position(NO_POS); + position_changed = true; + } + + m_focus = find_unselected_focus(); + + int before = 0; // number of entries before first selected + int after = 0; // number of entries after last selected + + while (before < n_entries && !m_entries[before]->selected) + before++; + + int to = before; + + for (int from = before; from < n_entries; from++) + { + PlaylistEntry * entry = m_entries[from].get(); + + if (entry->selected) + { + if (entry->queued) + { + m_queued.remove(m_queued.find(entry), 1); + update_flags |= QueueChanged; + } + + m_total_length -= entry->length; + after = 0; + } + else + { + m_entries[to++] = std::move(m_entries[from]); + after++; + } + } + + n_entries = to; + m_entries.remove(n_entries, -1); + + m_selected_count = 0; + m_selected_length = 0; + + number_entries(before, n_entries - before); + queue_update(Playlist::Structure, before, n_entries - after - before, + update_flags); + + if (position_changed) + { + if (aud_get_bool("advance_on_delete")) + change_position_to_next(aud_get_bool("repeat"), n_entries - after); + + queue_position_change(); + } +} + +void PlaylistData::sort_entries(Index<EntryPtr> & entries, + const CompareData & data) // static +{ + entries.sort([data](const EntryPtr & a, const EntryPtr & b) { + if (data.filename_compare) + return data.filename_compare(a->filename, b->filename); + else + return data.tuple_compare(a->tuple, b->tuple); + }); +} + +void PlaylistData::sort(const CompareData & data) +{ + sort_entries(m_entries, data); + + number_entries(0, m_entries.len()); + queue_update(Playlist::Structure, 0, m_entries.len()); +} + +void PlaylistData::sort_selected(const CompareData & data) +{ + int n_entries = m_entries.len(); + + Index<EntryPtr> selected; + + for (auto & entry : m_entries) + { + if (entry->selected) + selected.append(std::move(entry)); + } + + sort_entries(selected, data); + + int i = 0; + for (auto & entry : m_entries) + { + if (!entry) + entry = std::move(selected[i++]); + } + + number_entries(0, n_entries); + queue_update(Playlist::Structure, 0, n_entries); +} + +void PlaylistData::reverse_order() +{ + int n_entries = m_entries.len(); + + for (int i = 0; i < n_entries / 2; i++) + std::swap(m_entries[i], m_entries[n_entries - 1 - i]); + + number_entries(0, n_entries); + queue_update(Playlist::Structure, 0, n_entries); +} + +void PlaylistData::reverse_selected() +{ + int n_entries = m_entries.len(); + + int top = 0; + int bottom = n_entries - 1; + + while (1) + { + while (top < bottom && !m_entries[top]->selected) + top++; + while (top < bottom && !m_entries[bottom]->selected) + bottom--; + + if (top >= bottom) + break; + + std::swap(m_entries[top++], m_entries[bottom--]); + } + + number_entries(0, n_entries); + queue_update(Playlist::Structure, 0, n_entries); +} + +void PlaylistData::randomize_order() +{ + int n_entries = m_entries.len(); + + for (int i = 0; i < n_entries; i++) + std::swap(m_entries[i], m_entries[rand() % n_entries]); + + number_entries(0, n_entries); + queue_update(Playlist::Structure, 0, n_entries); +} + +void PlaylistData::randomize_selected() +{ + int n_entries = m_entries.len(); + + Index<PlaylistEntry *> selected; + + for (auto & entry : m_entries) + { + if (entry->selected) + selected.append(entry.get()); + } + + int n_selected = selected.len(); + + for (int i = 0; i < n_selected; i++) + { + int a = selected[i]->number; + int b = selected[rand() % n_selected]->number; + std::swap(m_entries[a], m_entries[b]); + } + + number_entries(0, n_entries); + queue_update(Playlist::Structure, 0, n_entries); +} + +int PlaylistData::queue_get_entry(int at) const +{ + return (at >= 0 && at < m_queued.len()) ? m_queued[at]->number : -1; +} + +int PlaylistData::queue_find_entry(int entry_num) const +{ + auto entry = entry_at(entry_num); + return (entry && entry->queued) ? m_queued.find((PlaylistEntry *)entry) + : -1; +} + +void PlaylistData::queue_insert(int at, int entry_num) +{ + auto entry = entry_at(entry_num); + if (!entry || entry->queued) + return; + + if (at < 0 || at > m_queued.len()) + m_queued.append(entry); + else + { + m_queued.insert(at, 1); + m_queued[at] = entry; + } + + entry->queued = true; + + queue_update(Playlist::Selection, entry_num, 1, QueueChanged); +} + +void PlaylistData::queue_insert_selected(int at) +{ + if (at < 0 || at > m_queued.len()) + at = m_queued.len(); + + Index<PlaylistEntry *> add; + int first = m_entries.len(); + int last = 0; + + for (auto & entry : m_entries) + { + if (!entry->selected || entry->queued) + continue; + + add.append(entry.get()); + entry->queued = true; + first = aud::min(first, entry->number); + last = entry->number; + } + + m_queued.move_from(add, 0, at, -1, true, true); + + if (first < m_entries.len()) + queue_update(Playlist::Selection, first, last + 1 - first, + QueueChanged); +} + +void PlaylistData::queue_remove(int at, int number) +{ + int queue_len = m_queued.len(); + + if (at < 0 || at > queue_len) + at = queue_len; + if (number < 0 || number > queue_len - at) + number = queue_len - at; + + int n_entries = m_entries.len(); + int first = n_entries, last = 0; + + for (int i = at; i < at + number; i++) + { + PlaylistEntry * entry = m_queued[i]; + entry->queued = false; + first = aud::min(first, entry->number); + last = entry->number; + } + + m_queued.remove(at, number); + + if (first < n_entries) + queue_update(Playlist::Selection, first, last + 1 - first, + QueueChanged); +} + +void PlaylistData::queue_remove_selected() +{ + int n_entries = m_entries.len(); + int first = n_entries, last = 0; + + for (int i = 0; i < m_queued.len();) + { + PlaylistEntry * entry = m_queued[i]; + + if (entry->selected) + { + m_queued.remove(i, 1); + entry->queued = false; + first = aud::min(first, entry->number); + last = entry->number; + } + else + i++; + } + + if (first < n_entries) + queue_update(Playlist::Selection, first, last + 1 - first, + QueueChanged); +} + +int PlaylistData::shuffle_pos_before(int ref_pos) const +{ + auto ref_entry = entry_at(ref_pos); + if (!ref_entry) + return -1; + + const PlaylistEntry * found = nullptr; + for (auto & entry : m_entries) + { + if (entry->shuffle_num > 0 && + entry->shuffle_num < ref_entry->shuffle_num && + (!found || entry->shuffle_num > found->shuffle_num)) + { + found = entry.get(); + } + } + + return found ? found->number : -1; +} + +PlaylistData::PosChange PlaylistData::shuffle_pos_after(int ref_pos, + bool by_album) const +{ + auto ref_entry = entry_at(ref_pos); + if (!ref_entry) + return NO_POS; + + // the reference entry can be beyond the end of the shuffle list + // if we are looking ahead multiple entries, as in next_album() + if (ref_entry->shuffle_num > 0) + { + // look for the next entry in the existing shuffle order + const PlaylistEntry * next = nullptr; + for (auto & entry : m_entries) + { + if (entry->shuffle_num > ref_entry->shuffle_num && + (!next || entry->shuffle_num < next->shuffle_num)) + { + next = entry.get(); + } + } + + if (next) + return {next->number, false}; + } + + if (by_album) + { + // look for the next entry in the album + auto next = entry_at(ref_pos + 1); + if (next && same_album(next->tuple, ref_entry->tuple)) + return {ref_pos + 1, true}; + } + + return NO_POS; +} + +PlaylistData::PosChange PlaylistData::shuffle_pos_random(bool repeat, + bool by_album) const +{ + Index<const PlaylistEntry *> choices; + const PlaylistEntry * prev_entry = nullptr; + + for (auto & entry : m_entries) + { + // skip already played entries (unless repeating) + // optionally skip all but first entry in album + if ((entry->shuffle_num == 0 || repeat) && + !(by_album && prev_entry && + same_album(entry->tuple, prev_entry->tuple))) + { + choices.append(entry.get()); + } + + prev_entry = entry.get(); + } + + if (choices.len()) + return {choices[rand() % choices.len()]->number, true}; + + return NO_POS; +} + +int PlaylistData::pos_before(int ref_pos, bool shuffle) const +{ + if (shuffle) + return shuffle_pos_before(ref_pos); + + return (ref_pos > 0) ? ref_pos - 1 : -1; +} + +PlaylistData::PosChange PlaylistData::pos_after(int ref_pos, bool shuffle, + bool by_album) const +{ + if (m_queued.len()) + return NO_POS; // let pos_new() handle queue entries + + if (shuffle) + return shuffle_pos_after(ref_pos, by_album); + + if (ref_pos >= 0 && ref_pos + 1 < m_entries.len()) + return {ref_pos + 1, true}; + + return NO_POS; +} + +PlaylistData::PosChange PlaylistData::pos_new(bool repeat, bool shuffle, + bool by_album, int hint_pos) const +{ + if (m_queued.len()) + return {m_queued[0]->number, true}; + + if (shuffle) + return shuffle_pos_random(repeat, by_album); + + if (hint_pos >= 0 && hint_pos < m_entries.len()) + return {hint_pos, true}; + + return NO_POS; +} + +PlaylistData::PosChange PlaylistData::pos_new_full(bool repeat, bool shuffle, + bool by_album, int hint_pos, + bool & repeated) const +{ + // first try to pick a new position *without* repeating + auto change = pos_new(false, shuffle, by_album, hint_pos); + repeated = false; + + if (change.new_pos < 0 && repeat) + { + change = pos_new(true, shuffle, by_album, 0); + repeated = (change.new_pos >= 0); + } + + return change; +} + +void PlaylistData::change_position(PosChange change) +{ + m_position = entry_at(change.new_pos); + resume_time = 0; + + /* move entry to top of shuffle list */ + if (m_position && change.update_shuffle) + m_position->shuffle_num = ++m_last_shuffle_num; + + /* remove from queue if it's the first entry */ + if (m_queued.len() && m_position == m_queued[0]) + { + m_queued.remove(0, 1); + m_position->queued = false; + queue_update(Playlist::Selection, m_position->number, 1, QueueChanged); + } +} + +bool PlaylistData::change_position_to_next(bool repeat, int hint_pos) +{ + bool shuffle = aud_get_bool("shuffle"); + bool by_album = aud_get_bool("album_shuffle"); + bool repeated = false; + + auto change = pos_after(position(), shuffle, by_album); + if (change.new_pos < 0) + change = pos_new_full(repeat, shuffle, by_album, hint_pos, repeated); + if (change.new_pos < 0) + return false; + + if (repeated) + shuffle_reset(); + + change_position(change); + return true; +} + +void PlaylistData::shuffle_reset() +{ + m_last_shuffle_num = 0; + + for (auto & entry : m_entries) + entry->shuffle_num = 0; +} + +Index<int> PlaylistData::shuffle_history() const +{ + Index<int> history; + + // create a list of all entries in the shuffle list + for (auto & entry : m_entries) + { + if (entry->shuffle_num) + history.append(entry->number); + } + + // sort by shuffle order + history.sort([this](int entry_a, int entry_b) { + return m_entries[entry_a]->shuffle_num - + m_entries[entry_b]->shuffle_num; + }); + + return history; +} + +void PlaylistData::shuffle_replay(const Index<int> & history) +{ + shuffle_reset(); + + // replay the given history, entry by entry + for (int entry_num : history) + { + auto entry = entry_at(entry_num); + if (entry) + entry->shuffle_num = ++m_last_shuffle_num; + } +} + +void PlaylistData::set_position(int entry_num) +{ + change_position({entry_num, true}); + queue_position_change(); +} + +bool PlaylistData::prev_song() +{ + bool shuffle = aud_get_bool("shuffle"); + int pos = pos_before(position(), shuffle); + if (pos < 0) + return false; + + // update shuffle list if entry didn't come from it + change_position({pos, !shuffle}); + queue_position_change(); + return true; +} + +bool PlaylistData::next_song(bool repeat) +{ + if (!change_position_to_next(repeat, -1)) + return false; + + queue_position_change(); + return true; +} + +bool PlaylistData::prev_album() +{ + bool shuffle = aud_get_bool("shuffle"); + int pos = position(); + + // find the start of the previous album + for (bool in_prev_album = false;;) + { + auto entry = entry_at(pos); + if (!entry) + return false; + + while (1) + { + auto prev_entry = entry_at(pos_before(pos, shuffle)); + if (!prev_entry || !same_album(entry->tuple, prev_entry->tuple)) + break; + + pos = prev_entry->number; + } + + if (in_prev_album) + break; // we're at the start of the previous album + + // we're at the start of the current album + // one more song back puts us in the previous album + pos = pos_before(pos, shuffle); + in_prev_album = true; + } + + // update shuffle list if entry didn't come from it + change_position({pos, !shuffle}); + queue_position_change(); + return true; +} + +bool PlaylistData::next_album(bool repeat) +{ + bool shuffle = aud_get_bool("shuffle"); + PosChange change = {position(), false}; + Index<PosChange> skipped; + bool repeated = false; + + auto entry = entry_at(change.new_pos); + if (!entry) + return false; + + // find the end of the album + while (1) + { + // album shuffle is always on for this function + change = pos_after(change.new_pos, shuffle, true); + + auto next_entry = entry_at(change.new_pos); + if (!next_entry || !same_album(entry->tuple, next_entry->tuple)) + break; + + skipped.append(change); + } + + // get one new position if there was nothing after the album + if (change.new_pos < 0) + { + change = pos_new_full(repeat, shuffle, true, -1, repeated); + if (change.new_pos < 0) + return false; + } + + if (repeated) + shuffle_reset(); + else + { + // add skipped songs to shuffle list + for (auto & skip : skipped) + change_position(skip); + } + + change_position(change); + queue_position_change(); + return true; +} + +int PlaylistData::next_unscanned_entry(int entry_num) const +{ + if (entry_num < 0) + return -1; + + for (; entry_num < m_entries.len(); entry_num++) + { + auto & entry = *m_entries[entry_num]; + + if (entry.tuple.state() == Tuple::Initial && + strncmp(entry.filename, "stdin://", 8)) // blacklist stdin + { + return entry_num; + } + } + + return -1; +} + +ScanRequest * PlaylistData::create_scan_request(PlaylistEntry * entry, + ScanRequest::Callback callback, + int extra_flags) +{ + int flags = extra_flags; + if (!entry->tuple.valid()) + flags |= SCAN_TUPLE; + + /* scanner uses Tuple::AudioFile from existing tuple, if valid */ + return new ScanRequest(entry->filename, flags, callback, entry->decoder, + (flags & SCAN_TUPLE) ? Tuple() : entry->tuple.ref()); +} + +void PlaylistData::update_entry_from_scan(PlaylistEntry * entry, + ScanRequest * request, + int update_flags) +{ + if (!entry->decoder) + entry->decoder = request->decoder; + + if (!entry->tuple.valid() && request->tuple.valid()) + { + set_entry_tuple(entry, std::move(request->tuple)); + queue_update(Playlist::Metadata, entry->number, 1, update_flags); + } + + if (!entry->decoder || !entry->tuple.valid()) + entry->error = request->error; + + if (entry->tuple.state() == Tuple::Initial) + { + entry->tuple.set_state(Tuple::Failed); + queue_update(Playlist::Metadata, entry->number, 1, update_flags); + } +} + +void PlaylistData::update_playback_entry(Tuple && tuple) +{ + /* don't update cuesheet entries with stream metadata */ + if (m_position && !m_position->tuple.is_set(Tuple::StartTime)) + { + set_entry_tuple(m_position, std::move(tuple)); + queue_update(Playlist::Metadata, m_position->number, 1); + } +} + +bool PlaylistData::entry_needs_rescan(PlaylistEntry * entry, bool need_decoder, + bool need_tuple) +{ + if (!strncmp(entry->filename, "stdin://", 8)) // blacklist stdin + return false; + + // check whether requested data (decoder and/or tuple) has been read + return (need_decoder && !entry->decoder) || + (need_tuple && !entry->tuple.valid()); +} + +void PlaylistData::reformat_titles() +{ + for (auto & entry : m_entries) + entry->format(); + + queue_update(Playlist::Metadata, 0, m_entries.len()); +} + +void PlaylistData::reset_tuples(bool selected_only) +{ + for (auto & entry : m_entries) + { + if (!selected_only || entry->selected) + set_entry_tuple(entry.get(), Tuple()); + } + + queue_update(Playlist::Metadata, 0, m_entries.len()); + pl_signal_rescan_needed(m_id); +} + +void PlaylistData::reset_tuple_of_file(const char * filename) +{ + bool found = false; + + for (auto & entry : m_entries) + { + if (!strcmp(entry->filename, filename)) + { + set_entry_tuple(entry.get(), Tuple()); + queue_update(Playlist::Metadata, entry->number, 1); + found = true; + } + } + + if (found) + pl_signal_rescan_needed(m_id); +} + +PlaylistEntry * PlaylistData::find_unselected_focus() +{ + if (!m_focus || !m_focus->selected) + return m_focus; + + int n_entries = m_entries.len(); + + for (int search = m_focus->number + 1; search < n_entries; search++) + { + if (!m_entries[search]->selected) + return m_entries[search].get(); + } + + for (int search = m_focus->number; search--;) + { + if (!m_entries[search]->selected) + return m_entries[search].get(); + } + + return nullptr; +} diff --git a/src/libaudcore/playlist-data.h b/src/libaudcore/playlist-data.h new file mode 100644 index 0000000..662261e --- /dev/null +++ b/src/libaudcore/playlist-data.h @@ -0,0 +1,201 @@ +/* + * playlist-data.h + * Copyright 2017 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef PLAYLIST_DATA_H +#define PLAYLIST_DATA_H + +#include "playlist.h" +#include "scanner.h" + +class TupleCompiler; +struct PlaylistEntry; + +class PlaylistData +{ +public: + /* update flags */ + enum + { + QueueChanged = (1 << 0), + DelayedUpdate = (1 << 1) + }; + + /* scan status */ + enum ScanStatus + { + NotScanning, + ScanActive, + ScanEnding + }; + + struct CompareData + { + Playlist::StringCompareFunc filename_compare; + Playlist::TupleCompareFunc tuple_compare; + }; + + PlaylistData(Playlist::ID * m_id, const char * title); + ~PlaylistData(); + + PlaylistEntry * entry_at(int i); + const PlaylistEntry * entry_at(int i) const; + + String entry_filename(int i) const; + PluginHandle * entry_decoder(int i, String * error = nullptr) const; + Tuple entry_tuple(int i, String * error = nullptr) const; + + void cancel_updates(); + void swap_updates(bool & position_changed); + + void insert_items(int at, Index<PlaylistAddItem> && items); + void remove_entries(int at, int number); + + int position() const; + int focus() const; + + bool entry_selected(int entry_num) const; + int n_selected(int at, int number) const; + + void set_focus(int entry_num); + + void select_entry(int entry_num, bool selected); + void select_all(bool selected); + int shift_entries(int entry_num, int distance); + void remove_selected(); + + void sort(const CompareData & data); + void sort_selected(const CompareData & data); + + void reverse_order(); + void randomize_order(); + void reverse_selected(); + void randomize_selected(); + + int queue_get_entry(int at) const; + int queue_find_entry(int entry_num) const; + + void queue_insert(int at, int entry_num); + void queue_insert_selected(int pos); + void queue_remove(int at, int number); + void queue_remove_selected(); + + Index<int> shuffle_history() const; + void shuffle_replay(const Index<int> & history); + + void set_position(int entry_num); + + bool prev_song(); + bool next_song(bool repeat); + bool prev_album(); + bool next_album(bool repeat); + + int next_unscanned_entry(int entry_num) const; + bool entry_needs_rescan(PlaylistEntry * entry, bool need_decoder, + bool need_tuple); + ScanRequest * create_scan_request(PlaylistEntry * entry, + ScanRequest::Callback callback, + int extra_flags); + void update_entry_from_scan(PlaylistEntry * entry, ScanRequest * request, + int update_flags); + void update_playback_entry(Tuple && tuple); + + void reformat_titles(); + void reset_tuples(bool selected_only); + void reset_tuple_of_file(const char * filename); + + Playlist::ID * id() const { return m_id; } + + int n_entries() const { return m_entries.len(); } + int n_queued() const { return m_queued.len(); } + + int64_t total_length() const { return m_total_length; } + int64_t selected_length() const { return m_selected_length; } + + const Playlist::Update & last_update() const { return m_last_update; } + bool update_pending() const + { + return m_next_update.level != Playlist::NoUpdate; + } + + static void update_formatter(); + static void cleanup_formatter(); + +private: + struct PosChange + { + int new_pos; + bool update_shuffle; + }; + + static void delete_entry(PlaylistEntry * entry); + typedef SmartPtr<PlaylistEntry, delete_entry> EntryPtr; + + void number_entries(int at, int length); + void set_entry_tuple(PlaylistEntry * entry, Tuple && tuple); + void queue_update(Playlist::UpdateLevel level, int at, int count, + int flags = 0); + void queue_position_change(); + + static void sort_entries(Index<EntryPtr> & entries, + const CompareData & data); + + int shuffle_pos_before(int ref_pos) const; + PosChange shuffle_pos_after(int ref_pos, bool by_album) const; + PosChange shuffle_pos_random(bool repeat, bool by_album) const; + + int pos_before(int ref_pos, bool shuffle) const; + PosChange pos_after(int ref_pos, bool shuffle, bool by_album) const; + PosChange pos_new(bool repeat, bool shuffle, bool by_album, + int hint_pos) const; + PosChange pos_new_full(bool repeat, bool shuffle, bool by_album, + int hint_pos, bool & repeated) const; + + void change_position(PosChange change); + bool change_position_to_next(bool repeat, int hint_pos); + void shuffle_reset(); + + PlaylistEntry * find_unselected_focus(); + +public: + bool modified; + ScanStatus scan_status; + String filename, title; + int resume_time; + +private: + Playlist::ID * m_id; + Index<EntryPtr> m_entries; + PlaylistEntry *m_position, *m_focus; + int m_selected_count; + int m_last_shuffle_num; + Index<PlaylistEntry *> m_queued; + int64_t m_total_length, m_selected_length; + Playlist::Update m_last_update, m_next_update; + bool m_position_changed; +}; + +/* callbacks or "signals" (in the QObject sense) */ +void pl_signal_entry_deleted(PlaylistEntry * entry); +void pl_signal_position_changed(Playlist::ID * id); +void pl_signal_update_queued(Playlist::ID * id, Playlist::UpdateLevel level, + int flags); +void pl_signal_rescan_needed(Playlist::ID * id); +void pl_signal_playlist_deleted(Playlist::ID * id); + +#endif // PLAYLIST_DATA_H diff --git a/src/libaudcore/playlist-files.cc b/src/libaudcore/playlist-files.cc new file mode 100644 index 0000000..c11c505 --- /dev/null +++ b/src/libaudcore/playlist-files.cc @@ -0,0 +1,189 @@ +/* + * playlist-files.c + * Copyright 2010-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "playlist-internal.h" + +#include "audstrings.h" +#include "i18n.h" +#include "interface.h" +#include "plugin.h" +#include "plugins-internal.h" +#include "runtime.h" + +EXPORT bool Playlist::filename_is_playlist(const char * filename) +{ + StringBuf ext = uri_get_extension(filename); + + if (ext) + { + for (PluginHandle * plugin : aud_plugin_list(PluginType::Playlist)) + { + if (aud_plugin_get_enabled(plugin) && + playlist_plugin_has_ext(plugin, ext)) + return true; + } + } + + return false; +} + +bool playlist_load(const char * filename, String & title, + Index<PlaylistAddItem> & items) +{ + AUDINFO("Loading playlist %s.\n", filename); + + StringBuf ext = uri_get_extension(filename); + bool plugin_found = false; + + if (ext) + { + for (PluginHandle * plugin : aud_plugin_list(PluginType::Playlist)) + { + if (!aud_plugin_get_enabled(plugin) || + !playlist_plugin_has_ext(plugin, ext)) + continue; + + AUDINFO("Trying playlist plugin %s.\n", + aud_plugin_get_name(plugin)); + plugin_found = true; + + auto pp = (PlaylistPlugin *)aud_plugin_get_header(plugin); + if (!pp) + continue; + + VFSFile file(filename, "r"); + if (!file) + { + aud_ui_show_error(str_printf(_("Error opening %s:\n%s"), + filename, file.error())); + return false; + } + + if (pp->load(filename, file, title, items)) + return true; + + title = String(); + items.clear(); + } + } + + if (plugin_found) + aud_ui_show_error(str_printf(_("Error loading %s."), filename)); + else + aud_ui_show_error(str_printf(_("Cannot load %s: unsupported file " + "name extension."), + filename)); + + return false; +} + +// This procedure is only used when loading playlists from ~/.config/audacious; +// hence, it is drastically simpler than the full-featured routines in adder.cc. +// All support for adding folders, cuesheets, subtunes, etc. is omitted here. +// Additionally, in order to avoid heavy I/O at startup, failed entries are not +// rescanned; they can be rescanned later by refreshing the playlist. */ +bool PlaylistEx::insert_flat_playlist(const char * filename) const +{ + String title; + Index<PlaylistAddItem> items; + + if (!playlist_load(filename, title, items)) + return false; + + if (title) + set_title(title); + + insert_flat_items(0, std::move(items)); + + return true; +} + +EXPORT bool Playlist::save_to_file(const char * filename, GetMode mode) const +{ + String title = get_title(); + + Index<PlaylistAddItem> items; + items.insert(0, n_entries()); + + int i = 0; + for (PlaylistAddItem & item : items) + { + item.filename = entry_filename(i); + item.tuple = entry_tuple(i, mode); + item.tuple.delete_fallbacks(); + i++; + } + + AUDINFO("Saving playlist %s.\n", filename); + + StringBuf ext = uri_get_extension(filename); + + if (ext) + { + for (PluginHandle * plugin : aud_plugin_list(PluginType::Playlist)) + { + if (!aud_plugin_get_enabled(plugin) || + !playlist_plugin_has_ext(plugin, ext)) + continue; + + PlaylistPlugin * pp = + (PlaylistPlugin *)aud_plugin_get_header(plugin); + if (!pp || !pp->can_save) + continue; + + VFSFile file(filename, "w"); + if (!file) + { + aud_ui_show_error(str_printf(_("Error opening %s:\n%s"), + filename, file.error())); + return false; + } + + if (pp->save(filename, file, title, items) && file.fflush() == 0) + return true; + + aud_ui_show_error(str_printf(_("Error saving %s."), filename)); + return false; + } + } + + aud_ui_show_error(str_printf( + _("Cannot save %s: unsupported file name extension."), filename)); + return false; +} + +EXPORT Index<Playlist::SaveFormat> Playlist::save_formats() +{ + Index<Playlist::SaveFormat> formats; + + for (auto plugin : aud_plugin_list(PluginType::Playlist)) + { + if (!aud_plugin_get_enabled(plugin) || + !playlist_plugin_can_save(plugin)) + continue; + + auto & format = formats.append(); + format.name = String(aud_plugin_get_name(plugin)); + + for (auto & ext : playlist_plugin_get_exts(plugin)) + format.exts.append(ext); + } + + return formats; +} diff --git a/src/libaudcore/playlist-internal.h b/src/libaudcore/playlist-internal.h new file mode 100644 index 0000000..6333ecb --- /dev/null +++ b/src/libaudcore/playlist-internal.h @@ -0,0 +1,78 @@ +/* + * playlist-internal.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_PLAYLIST_INTERNAL_H +#define LIBAUDCORE_PLAYLIST_INTERNAL_H + +#include "playlist.h" +#include "vfs.h" + +class InputPlugin; + +struct DecodeInfo +{ + String filename; + InputPlugin * ip = nullptr; + VFSFile file; + String error; +}; + +/* extended handle for accessing internal playlist functions */ +class PlaylistEx : public Playlist +{ +public: + PlaylistEx(Playlist::ID * id = nullptr) : Playlist(id) {} + PlaylistEx(Playlist playlist) : Playlist(playlist) {} + + int stamp() const; + + static Playlist insert_with_stamp(int at, int stamp); + + bool get_modified() const; + void set_modified(bool modified) const; + + bool insert_flat_playlist(const char * filename) const; + void insert_flat_items(int at, Index<PlaylistAddItem> && items) const; +}; + +/* playlist.cc */ +void playlist_init(); +void playlist_enable_scan(bool enable); +void playlist_clear_updates(); +void playlist_end(); + +void playlist_load_state(); +void playlist_save_state(); + +DecodeInfo playback_entry_read(int serial); +void playback_entry_set_tuple(int serial, Tuple && tuple); + +/* playlist-cache.cc */ +void playlist_cache_load(Index<PlaylistAddItem> & items); +void playlist_cache_clear(void * = nullptr); + +/* playlist-files.cc */ +bool playlist_load(const char * filename, String & title, + Index<PlaylistAddItem> & items); + +/* playlist-utils.cc */ +void load_playlists(); +void save_playlists(bool exiting); + +#endif diff --git a/src/libaudcore/playlist-utils.cc b/src/libaudcore/playlist-utils.cc new file mode 100644 index 0000000..ff78a2f --- /dev/null +++ b/src/libaudcore/playlist-utils.cc @@ -0,0 +1,433 @@ +/* + * playlist-utils.c + * Copyright 2009-2011 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "playlist-internal.h" + +#include <stdlib.h> +#include <string.h> + +#include <glib/gstdio.h> + +#include "audstrings.h" +#include "hook.h" +#include "multihash.h" +#include "runtime.h" +#include "tuple.h" +#include "vfs.h" + +static const char * get_basename(const char * filename) +{ + const char * slash = strrchr(filename, '/'); + return slash ? slash + 1 : filename; +} + +static int filename_compare_path(const char * a, const char * b) +{ + int dirlen_a = get_basename(a) - a; + int dirlen_b = get_basename(b) - b; + + // if one folder is a subfolder of the other, sort it last + if (dirlen_a != dirlen_b && memcmp(a, b, aud::min(dirlen_a, dirlen_b)) == 0) + return dirlen_a - dirlen_b; + + // in all other cases, compare the entire paths + return str_compare_encoded(a, b); +} + +static int filename_compare_basename(const char * a, const char * b) +{ + return str_compare_encoded(get_basename(a), get_basename(b)); +} + +static int tuple_compare_string(const Tuple & a, const Tuple & b, + Tuple::Field field) +{ + String string_a = a.get_str(field); + String string_b = b.get_str(field); + + if (!string_a) + return (!string_b) ? 0 : -1; + + return (!string_b) ? 1 : str_compare(string_a, string_b); +} + +static int tuple_compare_int(const Tuple & a, const Tuple & b, + Tuple::Field field) +{ + if (a.get_value_type(field) != Tuple::Int) + return (b.get_value_type(field) != Tuple::Int) ? 0 : -1; + if (b.get_value_type(field) != Tuple::Int) + return 1; + + int int_a = a.get_int(field); + int int_b = b.get_int(field); + + return (int_a < int_b) ? -1 : (int_a > int_b); +} + +static int tuple_compare_title(const Tuple & a, const Tuple & b) +{ + return tuple_compare_string(a, b, Tuple::Title); +} +static int tuple_compare_album(const Tuple & a, const Tuple & b) +{ + return tuple_compare_string(a, b, Tuple::Album); +} +static int tuple_compare_artist(const Tuple & a, const Tuple & b) +{ + return tuple_compare_string(a, b, Tuple::Artist); +} +static int tuple_compare_album_artist(const Tuple & a, const Tuple & b) +{ + return tuple_compare_string(a, b, Tuple::AlbumArtist); +} +static int tuple_compare_date(const Tuple & a, const Tuple & b) +{ + return tuple_compare_int(a, b, Tuple::Year); +} +static int tuple_compare_genre(const Tuple & a, const Tuple & b) +{ + return tuple_compare_string(a, b, Tuple::Genre); +} +static int tuple_compare_track(const Tuple & a, const Tuple & b) +{ + return tuple_compare_int(a, b, Tuple::Track); +} +static int tuple_compare_formatted_title(const Tuple & a, const Tuple & b) +{ + return tuple_compare_string(a, b, Tuple::FormattedTitle); +} +static int tuple_compare_length(const Tuple & a, const Tuple & b) +{ + return tuple_compare_int(a, b, Tuple::Length); +} +static int tuple_compare_comment(const Tuple & a, const Tuple & b) +{ + return tuple_compare_string(a, b, Tuple::Comment); +} + +static const Playlist::StringCompareFunc filename_comparisons[] = { + filename_compare_path, // path + filename_compare_basename, // filename + nullptr, // title + nullptr, // album + nullptr, // artist + nullptr, // album artist + nullptr, // date + nullptr, // genre + nullptr, // track + nullptr, // formatted title + nullptr, // length + nullptr // comment +}; + +static const Playlist::TupleCompareFunc tuple_comparisons[] = { + nullptr, // path + nullptr, // filename + tuple_compare_title, + tuple_compare_album, + tuple_compare_artist, + tuple_compare_album_artist, + tuple_compare_date, + tuple_compare_genre, + tuple_compare_track, + tuple_compare_formatted_title, + tuple_compare_length, + tuple_compare_comment}; + +static_assert(aud::n_elems(filename_comparisons) == Playlist::n_sort_types && + aud::n_elems(tuple_comparisons) == Playlist::n_sort_types, + "Update playlist comparison functions"); + +EXPORT void Playlist::sort_entries(SortType scheme) const +{ + if (filename_comparisons[scheme]) + sort_by_filename(filename_comparisons[scheme]); + else if (tuple_comparisons[scheme]) + sort_by_tuple(tuple_comparisons[scheme]); +} + +EXPORT void Playlist::sort_selected(SortType scheme) const +{ + if (filename_comparisons[scheme]) + sort_selected_by_filename(filename_comparisons[scheme]); + else if (tuple_comparisons[scheme]) + sort_selected_by_tuple(tuple_comparisons[scheme]); +} + +/* FIXME: this considers empty fields as duplicates */ +EXPORT void Playlist::remove_duplicates(SortType scheme) const +{ + int entries = n_entries(); + if (entries < 1) + return; + + select_all(false); + + if (filename_comparisons[scheme]) + { + StringCompareFunc compare = filename_comparisons[scheme]; + + sort_by_filename(compare); + String last = entry_filename(0); + + for (int i = 1; i < entries; i++) + { + String current = entry_filename(i); + + if (compare(last, current) == 0) + select_entry(i, true); + + last = current; + } + } + else if (tuple_comparisons[scheme]) + { + TupleCompareFunc compare = tuple_comparisons[scheme]; + + sort_by_tuple(compare); + Tuple last = entry_tuple(0); + + for (int i = 1; i < entries; i++) + { + Tuple current = entry_tuple(i); + + if (last.valid() && current.valid() && compare(last, current) == 0) + select_entry(i, true); + + last = std::move(current); + } + } + + remove_selected(); +} + +EXPORT void Playlist::remove_unavailable() const +{ + int entries = n_entries(); + + select_all(false); + + for (int i = 0; i < entries; i++) + { + String filename = entry_filename(i); + + /* use VFS_NO_ACCESS since VFS_EXISTS doesn't distinguish between + * inaccessible files and URI schemes that don't support file_test() */ + if (VFSFile::test_file(filename, VFS_NO_ACCESS)) + select_entry(i, true); + } + + remove_selected(); +} + +EXPORT void Playlist::select_by_patterns(const Tuple & patterns) const +{ + int entries = n_entries(); + + select_all(true); + + for (Tuple::Field field : + {Tuple::Title, Tuple::Album, Tuple::Artist, Tuple::Basename}) + { + String pattern = patterns.get_str(field); + GRegex * regex; + + if (!pattern || !pattern[0] || + !(regex = g_regex_new(pattern, G_REGEX_CASELESS, + (GRegexMatchFlags)0, nullptr))) + continue; + + for (int i = 0; i < entries; i++) + { + if (!entry_selected(i)) + continue; + + Tuple tuple = entry_tuple(i); + String string = tuple.get_str(field); + + if (!string || + !g_regex_match(regex, string, (GRegexMatchFlags)0, nullptr)) + select_entry(i, false); + } + + g_regex_unref(regex); + } +} + +static StringBuf make_playlist_path(int playlist) +{ + if (!playlist) + return filename_build( + {aud_get_path(AudPath::UserDir), "playlist.xspf"}); + + return filename_build({aud_get_path(AudPath::UserDir), + str_printf("playlist_%02d.xspf", 1 + playlist)}); +} + +static void load_playlists_real() +{ + const char * folder = aud_get_path(AudPath::PlaylistDir); + + /* old (v3.1 and earlier) naming scheme */ + + int count; + for (count = 0;; count++) + { + StringBuf path = make_playlist_path(count); + if (!g_file_test(path, G_FILE_TEST_EXISTS)) + break; + + PlaylistEx playlist = Playlist::insert_playlist(count); + playlist.insert_flat_playlist(filename_to_uri(path)); + playlist.set_modified(true); + } + + /* unique ID-based naming scheme */ + + StringBuf order_path = filename_build({folder, "order"}); + auto order_string = VFSFile::read_file( + order_path, VFSReadOptions(VFS_APPEND_NULL | VFS_IGNORE_MISSING)); + auto order = str_list_to_index(order_string.begin(), " "); + + for (int i = 0; i < order.len(); i++) + { + const char * number = order[i]; + + StringBuf path = + filename_build({folder, str_concat({number, ".audpl"})}); + if (!g_file_test(path, G_FILE_TEST_EXISTS)) + path = filename_build({folder, str_concat({number, ".xspf"})}); + + PlaylistEx playlist = + PlaylistEx::insert_with_stamp(count + i, atoi(number)); + playlist.insert_flat_playlist(filename_to_uri(path)); + playlist.set_modified(g_str_has_suffix(path, ".xspf")); + } + + if (!Playlist::n_playlists()) + Playlist::insert_playlist(0); +} + +static void save_playlists_real() +{ + int lists = Playlist::n_playlists(); + const char * folder = aud_get_path(AudPath::PlaylistDir); + + /* save playlists */ + + Index<String> order; + SimpleHash<String, bool> saved; + + for (int i = 0; i < lists; i++) + { + PlaylistEx playlist = Playlist::by_index(i); + StringBuf number = int_to_str(playlist.stamp()); + StringBuf name = str_concat({number, ".audpl"}); + + if (playlist.get_modified()) + { + StringBuf path = filename_build({folder, name}); + playlist.save_to_file(filename_to_uri(path), Playlist::NoWait); + playlist.set_modified(false); + } + + order.append(String(number)); + saved.add(String(name), true); + } + + StringBuf order_string = index_to_str_list(order, " "); + StringBuf order_path = filename_build({folder, "order"}); + auto old_order_string = VFSFile::read_file( + order_path, VFSReadOptions(VFS_APPEND_NULL | VFS_IGNORE_MISSING)); + + if (strcmp(old_order_string.begin(), order_string)) + VFSFile::write_file(order_path, (const char *)order_string, + order_string.len()); + + /* clean up deleted playlists and files from old naming scheme */ + + g_unlink(make_playlist_path(0)); + + GDir * dir = g_dir_open(folder, 0, nullptr); + if (!dir) + return; + + const char * name; + while ((name = g_dir_read_name(dir))) + { + if (!g_str_has_suffix(name, ".audpl") && + !g_str_has_suffix(name, ".xspf")) + continue; + + if (!saved.lookup(String(name))) + g_unlink(filename_build({folder, name})); + } + + g_dir_close(dir); +} + +static bool hooks_added, state_changed; + +static void update_cb(void * data, void *) +{ + auto level = aud::from_ptr<Playlist::UpdateLevel>(data); + if (level >= Playlist::Metadata) + state_changed = true; +} + +static void state_cb(void * data, void * user) { state_changed = true; } + +void load_playlists() +{ + load_playlists_real(); + playlist_load_state(); + + state_changed = false; + + if (!hooks_added) + { + hook_associate("playlist update", update_cb, nullptr); + hook_associate("playlist activate", state_cb, nullptr); + hook_associate("playlist position", state_cb, nullptr); + + hooks_added = true; + } +} + +void save_playlists(bool exiting) +{ + save_playlists_real(); + + /* on exit, save resume states */ + if (state_changed || exiting) + { + playlist_save_state(); + state_changed = false; + } + + if (exiting && hooks_added) + { + hook_dissociate("playlist update", update_cb); + hook_dissociate("playlist activate", state_cb); + hook_dissociate("playlist position", state_cb); + + hooks_added = false; + } +} diff --git a/src/libaudcore/playlist.cc b/src/libaudcore/playlist.cc new file mode 100644 index 0000000..02190f3 --- /dev/null +++ b/src/libaudcore/playlist.cc @@ -0,0 +1,1305 @@ +/* + * playlist.cc + * Copyright 2009-2017 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "playlist-internal.h" + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include <glib/gstdio.h> + +#include "audstrings.h" +#include "drct.h" +#include "hook.h" +#include "i18n.h" +#include "internal.h" +#include "list.h" +#include "mainloop.h" +#include "multihash.h" +#include "parse.h" +#include "playlist-data.h" +#include "runtime.h" +#include "threads.h" + +enum +{ + ResumeStop, + ResumePlay, + ResumePause +}; + +/* update hooks */ +enum +{ + SetActive = (1 << 0), + SetPlaying = (1 << 1), + PlaybackBegin = (1 << 2), + PlaybackStop = (1 << 3) +}; + +enum class UpdateState +{ + None, + Delayed, + Queued +}; + +#define STATE_FILE "playlist-state" + +#define ENTER_GET_PLAYLIST(...) \ + auto mh = mutex.take(); \ + PlaylistData * playlist = m_id ? m_id->data : nullptr; \ + if (!playlist) \ + return __VA_ARGS__ + +#define SIMPLE_WRAPPER(type, failcode, func, ...) \ + ENTER_GET_PLAYLIST(failcode); \ + return playlist->func(__VA_ARGS__) + +#define SIMPLE_VOID_WRAPPER(func, ...) \ + ENTER_GET_PLAYLIST(); \ + playlist->func(__VA_ARGS__) + +static const char * const default_title = N_("New Playlist"); +static const char * const temp_title = N_("Now Playing"); + +static aud::mutex mutex; +static aud::condvar condvar; + +/* + * Each playlist is associated with its own ID struct, which contains a unique + * integer "stamp" (this is the source of the internal filenames 1000.audpl, + * 1001.audpl, etc.) The ID struct also serves as a "weak" pointer to the + * actual data, and persists even after the playlist itself is destroyed. + * The IDs are stored in a hash table, allowing lookup by stamp. + * + * In brief: Playlist (public handle) + * points to -> + * Playlist::ID (unique ID / weak pointer) + * points to -> + * PlaylistData (actual playlist data) + */ +struct Playlist::ID +{ + int stamp; // integer stamp, determines filename + int index; // display order + PlaylistData * data; // pointer to actual playlist data +}; + +static SimpleHash<IntHashKey, Playlist::ID> id_table; +static int next_stamp = 1000; + +static Index<SmartPtr<PlaylistData>> playlists; +static Playlist::ID * active_id = nullptr; +static Playlist::ID * playing_id = nullptr; +static int resume_playlist = -1; +static bool resume_paused = false; + +static QueuedFunc queued_update; +static Playlist::UpdateLevel update_level; +static int update_hooks; +static UpdateState update_state; + +struct ScanItem : public ListNode +{ + ScanItem(PlaylistData * playlist, PlaylistEntry * entry, + ScanRequest * request, bool for_playback) + : playlist(playlist), entry(entry), request(request), + for_playback(for_playback), handled_by_playback(false) + { + } + + PlaylistData * playlist; + PlaylistEntry * entry; + ScanRequest * request; + bool for_playback; + bool handled_by_playback; +}; + +static bool scan_enabled_nominal, scan_enabled; +static int scan_playlist, scan_row; +static List<ScanItem> scan_list; + +static void scan_finish(ScanRequest * request); +static void scan_cancel(PlaylistEntry * entry); +static void scan_restart(); + +/* creates a new playlist with the requested stamp (if not already in use) */ +static Playlist::ID * create_playlist(int stamp) +{ + Playlist::ID * id; + + if (stamp >= 0 && !id_table.lookup(stamp)) + id = id_table.add(stamp, {stamp, -1, nullptr}); + else + { + while (id_table.lookup(next_stamp)) + next_stamp++; + + id = id_table.add(next_stamp, {next_stamp, -1, nullptr}); + } + + id->data = new PlaylistData(id, _(default_title)); + + return id; +} + +static void number_playlists(int at, int length) +{ + for (int i = at; i < at + length; i++) + playlists[i]->id()->index = i; +} + +static void update(void *) +{ + auto mh = mutex.take(); + + int hooks = update_hooks; + auto level = update_level; + + Index<PlaylistEx> position_change_list; + + for (auto & p : playlists) + { + bool position_changed = false; + p->swap_updates(position_changed); + + if (position_changed) + position_change_list.append(p->id()); + } + + update_hooks = 0; + update_level = Playlist::NoUpdate; + update_state = UpdateState::None; + event_queue_unpause(); + + mh.unlock(); + + if (level != Playlist::NoUpdate) + hook_call("playlist update", aud::to_ptr(level)); + + for (PlaylistEx playlist : position_change_list) + hook_call("playlist position", aud::to_ptr(playlist)); + + if ((hooks & SetActive)) + hook_call("playlist activate", nullptr); + if ((hooks & SetPlaying)) + hook_call("playlist set playing", nullptr); + if ((hooks & PlaybackBegin)) + hook_call("playback begin", nullptr); + if ((hooks & PlaybackStop)) + hook_call("playback stop", nullptr); +} + +static void queue_update() +{ + if (update_state < UpdateState::Queued) + { + event_queue_pause(); // give playlist updates priority + queued_update.queue(update, nullptr); + update_state = UpdateState::Queued; + } +} + +static void queue_update_hooks(int hooks) +{ + if ((hooks & PlaybackBegin)) + update_hooks &= ~PlaybackStop; + if ((hooks & PlaybackStop)) + update_hooks &= ~PlaybackBegin; + + update_hooks |= hooks; + queue_update(); +} + +static void queue_global_update(Playlist::UpdateLevel level, int flags = 0) +{ + if (level == Playlist::Structure) + scan_restart(); + + if ((flags & PlaylistData::DelayedUpdate)) + { + if (update_state < UpdateState::Delayed) + { + queued_update.queue(250, update, nullptr); + update_state = UpdateState::Delayed; + } + } + else + { + queue_update(); + } + + update_level = aud::max(update_level, level); +} + +EXPORT bool Playlist::update_pending_any() +{ + auto mh = mutex.take(); + return (update_level != Playlist::NoUpdate); +} + +EXPORT void Playlist::process_pending_update() { update(nullptr); } + +EXPORT bool Playlist::scan_in_progress() const +{ + ENTER_GET_PLAYLIST(false); + return (playlist->scan_status != PlaylistData::NotScanning); +} + +EXPORT bool Playlist::scan_in_progress_any() +{ + auto mh = mutex.take(); + + for (auto & p : playlists) + { + if (p->scan_status != PlaylistData::NotScanning) + return true; + } + + return false; +} + +static ScanItem * scan_list_find_entry(PlaylistEntry * entry) +{ + auto match = [entry](const ScanItem & item) { return item.entry == entry; }; + + return scan_list.find(match); +} + +static void scan_queue_entry(PlaylistData * playlist, PlaylistEntry * entry, + bool for_playback = false) +{ + int extra_flags = for_playback ? (SCAN_IMAGE | SCAN_FILE) : 0; + auto request = + playlist->create_scan_request(entry, scan_finish, extra_flags); + + scan_list.append(new ScanItem(playlist, entry, request, for_playback)); + + /* playback entry will be scanned by the playback thread */ + if (!for_playback) + scanner_request(request); +} + +static void scan_reset_playback() +{ + auto match = [](const ScanItem & item) { return item.for_playback; }; + + ScanItem * item = scan_list.find(match); + if (!item) + return; + + item->for_playback = false; + + /* if playback was canceled before the entry was scanned, requeue it */ + if (!item->handled_by_playback) + scanner_request(item->request); +} + +static void scan_check_complete(PlaylistData * playlist) +{ + auto match = [playlist](const ScanItem & item) { + return item.playlist == playlist; + }; + + if (playlist->scan_status != PlaylistData::ScanEnding || + scan_list.find(match)) + return; + + playlist->scan_status = PlaylistData::NotScanning; + + if (update_state == UpdateState::Delayed) + queue_update(); + + event_queue_cancel("playlist scan complete"); + event_queue("playlist scan complete", nullptr); +} + +static bool scan_queue_next_entry() +{ + if (!scan_enabled) + return false; + + while (scan_playlist < playlists.len()) + { + PlaylistData * playlist = playlists[scan_playlist].get(); + + if (playlist->scan_status == PlaylistData::ScanActive) + { + while (1) + { + scan_row = playlist->next_unscanned_entry(scan_row); + if (scan_row < 0) + break; + + auto entry = playlist->entry_at(scan_row); + if (!scan_list_find_entry(entry)) + { + scan_queue_entry(playlist, entry); + return true; + } + + scan_row++; + } + + playlist->scan_status = PlaylistData::ScanEnding; + scan_check_complete(playlist); + } + + scan_playlist++; + scan_row = 0; + } + + return false; +} + +static void scan_schedule() +{ + int scheduled = 0; + + for (ScanItem * item = scan_list.head(); item; item = scan_list.next(item)) + { + if (++scheduled >= SCAN_THREADS) + return; + } + + while (scan_queue_next_entry()) + { + if (++scheduled >= SCAN_THREADS) + return; + } +} + +static void scan_finish(ScanRequest * request) +{ + auto mh = mutex.take(); + + auto match = [request](const ScanItem & item) { + return item.request == request; + }; + + ScanItem * item = scan_list.find(match); + if (!item) + return; + + PlaylistData * playlist = item->playlist; + PlaylistEntry * entry = item->entry; + + scan_list.remove(item); + + // only use delayed update if a scan is still in progress + int update_flags = 0; + if (scan_enabled && playlist->scan_status != PlaylistData::NotScanning) + update_flags = PlaylistData::DelayedUpdate; + + playlist->update_entry_from_scan(entry, request, update_flags); + + delete item; + + scan_check_complete(playlist); + scan_schedule(); + + condvar.notify_all(); +} + +static void scan_cancel(PlaylistEntry * entry) +{ + ScanItem * item = scan_list_find_entry(entry); + if (!item) + return; + + scan_list.remove(item); + delete (item); +} + +static void scan_restart() +{ + scan_playlist = 0; + scan_row = 0; + scan_schedule(); +} + +/* mutex may be unlocked during the call */ +static void wait_for_entry(aud::mutex::holder & mh, PlaylistData * playlist, + int entry_num, bool need_decoder, bool need_tuple) +{ + bool scan_started = false; + + while (1) + { + PlaylistEntry * entry = playlist->entry_at(entry_num); + + // check whether entry is deleted or has already been scanned + if (!entry || + !playlist->entry_needs_rescan(entry, need_decoder, need_tuple)) + return; + + // start scan if not already running ... + if (!scan_list_find_entry(entry)) + { + // ... but only once + if (scan_started) + return; + + scan_queue_entry(playlist, entry); + } + + // wait for scan to finish + scan_started = true; + condvar.wait(mh); + } +} + +static void start_playback_locked(int seek_time, bool pause) +{ + art_clear_current(); + scan_reset_playback(); + + playback_play(seek_time, pause); + + auto playlist = playing_id->data; + auto entry = playlist->entry_at(playlist->position()); + + // playback always begins with a rescan of the current entry in order to + // open the file, ensure a valid tuple, and read album art + scan_cancel(entry); + scan_queue_entry(playlist, entry, true); +} + +static void stop_playback_locked() +{ + art_clear_current(); + scan_reset_playback(); + + playback_stop(); +} + +void pl_signal_entry_deleted(PlaylistEntry * entry) { scan_cancel(entry); } + +void pl_signal_position_changed(Playlist::ID * id) +{ + queue_update(); + + if (id == playing_id) + { + if (id->data->position() >= 0) + { + start_playback_locked(0, aud_drct_get_paused()); + queue_update_hooks(PlaybackBegin); + } + else + { + playing_id = nullptr; + stop_playback_locked(); + queue_update_hooks(SetPlaying | PlaybackStop); + } + } +} + +void pl_signal_update_queued(Playlist::ID * id, Playlist::UpdateLevel level, + int flags) +{ + auto playlist = id->data; + + if (level == Playlist::Structure) + playlist->scan_status = PlaylistData::ScanActive; + + if (level >= Playlist::Metadata) + { + int pos = playlist->position(); + if (id == playing_id && pos >= 0) + playback_set_info(pos, playlist->entry_tuple(pos)); + + playlist->modified = true; + } + + queue_global_update(level, flags); +} + +void pl_signal_rescan_needed(Playlist::ID * id) +{ + id->data->scan_status = PlaylistData::ScanActive; + scan_restart(); +} + +void pl_signal_playlist_deleted(Playlist::ID * id) +{ + /* break weak pointer link */ + id->data = nullptr; + id->index = -1; +} + +static void pl_hook_reformat_titles(void *, void *) +{ + auto mh = mutex.take(); + + PlaylistData::update_formatter(); + + for (auto & playlist : playlists) + playlist->reformat_titles(); +} + +static void pl_hook_trigger_scan(void *, void *) +{ + auto mh = mutex.take(); + scan_enabled = scan_enabled_nominal && !aud_get_bool("metadata_on_play"); + scan_restart(); +} + +void playlist_init() +{ + srand(time(nullptr)); + + auto mh = mutex.take(); + + PlaylistData::update_formatter(); + + update_level = Playlist::NoUpdate; + update_hooks = 0; + update_state = UpdateState::None; + scan_enabled = scan_enabled_nominal = false; + scan_playlist = scan_row = 0; + + mh.unlock(); + + hook_associate("set generic_title_format", pl_hook_reformat_titles, + nullptr); + hook_associate("set leading_zero", pl_hook_reformat_titles, nullptr); + hook_associate("set metadata_fallbacks", pl_hook_reformat_titles, nullptr); + hook_associate("set show_hours", pl_hook_reformat_titles, nullptr); + hook_associate("set show_numbers_in_pl", pl_hook_reformat_titles, nullptr); + hook_associate("set metadata_on_play", pl_hook_trigger_scan, nullptr); +} + +void playlist_enable_scan(bool enable) +{ + auto mh = mutex.take(); + + scan_enabled_nominal = enable; + scan_enabled = scan_enabled_nominal && !aud_get_bool("metadata_on_play"); + scan_restart(); +} + +void playlist_clear_updates() +{ + auto mh = mutex.take(); + + /* clear updates queued during init sequence */ + for (auto & playlist : playlists) + playlist->cancel_updates(); + + queued_update.stop(); + update_level = Playlist::NoUpdate; + update_hooks = 0; + update_state = UpdateState::None; + event_queue_unpause(); +} + +void playlist_end() +{ + hook_dissociate("set generic_title_format", pl_hook_reformat_titles); + hook_dissociate("set leading_zero", pl_hook_reformat_titles); + hook_dissociate("set metadata_fallbacks", pl_hook_reformat_titles); + hook_dissociate("set show_hours", pl_hook_reformat_titles); + hook_dissociate("set show_numbers_in_pl", pl_hook_reformat_titles); + hook_dissociate("set metadata_on_play", pl_hook_trigger_scan); + + playlist_cache_clear(); + + auto mh = mutex.take(); + + /* playback should already be stopped */ + assert(!playing_id); + assert(!scan_list.head()); + + queued_update.stop(); + + active_id = nullptr; + resume_playlist = -1; + resume_paused = false; + + playlists.clear(); + id_table.clear(); + + PlaylistData::cleanup_formatter(); +} + +EXPORT int Playlist::n_entries() const { SIMPLE_WRAPPER(int, 0, n_entries); } +EXPORT void Playlist::remove_entries(int at, int number) const +{ + SIMPLE_VOID_WRAPPER(remove_entries, at, number); +} +EXPORT String Playlist::entry_filename(int entry_num) const +{ + SIMPLE_WRAPPER(String, String(), entry_filename, entry_num); +} + +EXPORT int Playlist::get_position() const { SIMPLE_WRAPPER(int, -1, position); } +EXPORT void Playlist::set_position(int entry_num) const +{ + SIMPLE_VOID_WRAPPER(set_position, entry_num); +} +EXPORT bool Playlist::prev_song() const +{ + SIMPLE_WRAPPER(bool, false, prev_song); +} +EXPORT bool Playlist::prev_album() const +{ + SIMPLE_WRAPPER(bool, false, prev_album); +} +EXPORT bool Playlist::next_song(bool repeat) const +{ + SIMPLE_WRAPPER(bool, false, next_song, repeat); +} +EXPORT bool Playlist::next_album(bool repeat) const +{ + SIMPLE_WRAPPER(bool, false, next_album, repeat); +} +EXPORT int Playlist::get_focus() const { SIMPLE_WRAPPER(int, -1, focus); } +EXPORT void Playlist::set_focus(int entry_num) const +{ + SIMPLE_VOID_WRAPPER(set_focus, entry_num); +} +EXPORT bool Playlist::entry_selected(int entry_num) const +{ + SIMPLE_WRAPPER(bool, false, entry_selected, entry_num); +} +EXPORT void Playlist::select_entry(int entry_num, bool selected) const +{ + SIMPLE_VOID_WRAPPER(select_entry, entry_num, selected); +} +EXPORT int Playlist::n_selected(int at, int number) const +{ + SIMPLE_WRAPPER(int, 0, n_selected, at, number); +} +EXPORT void Playlist::select_all(bool selected) const +{ + SIMPLE_VOID_WRAPPER(select_all, selected); +} +EXPORT int Playlist::shift_entries(int entry_num, int distance) const +{ + SIMPLE_WRAPPER(int, 0, shift_entries, entry_num, distance); +} +EXPORT void Playlist::remove_selected() const +{ + SIMPLE_VOID_WRAPPER(remove_selected); +} + +EXPORT void Playlist::sort_by_filename(StringCompareFunc compare) const +{ + SIMPLE_VOID_WRAPPER(sort, {compare, nullptr}); +} +EXPORT void Playlist::sort_by_tuple(TupleCompareFunc compare) const +{ + SIMPLE_VOID_WRAPPER(sort, {nullptr, compare}); +} +EXPORT void Playlist::sort_selected_by_filename(StringCompareFunc compare) const +{ + SIMPLE_VOID_WRAPPER(sort_selected, {compare, nullptr}); +} +EXPORT void Playlist::sort_selected_by_tuple(TupleCompareFunc compare) const +{ + SIMPLE_VOID_WRAPPER(sort_selected, {nullptr, compare}); +} +EXPORT void Playlist::reverse_order() const +{ + SIMPLE_VOID_WRAPPER(reverse_order); +} +EXPORT void Playlist::reverse_selected() const +{ + SIMPLE_VOID_WRAPPER(reverse_selected); +} +EXPORT void Playlist::randomize_order() const +{ + SIMPLE_VOID_WRAPPER(randomize_order); +} +EXPORT void Playlist::randomize_selected() const +{ + SIMPLE_VOID_WRAPPER(randomize_selected); +} + +EXPORT void Playlist::rescan_all() const +{ + SIMPLE_VOID_WRAPPER(reset_tuples, false); +} +EXPORT void Playlist::rescan_selected() const +{ + SIMPLE_VOID_WRAPPER(reset_tuples, true); +} + +EXPORT int64_t Playlist::total_length_ms() const +{ + SIMPLE_WRAPPER(int64_t, 0, total_length); +} +EXPORT int64_t Playlist::selected_length_ms() const +{ + SIMPLE_WRAPPER(int64_t, 0, selected_length); +} + +EXPORT int Playlist::n_queued() const { SIMPLE_WRAPPER(int, 0, n_queued); } +EXPORT void Playlist::queue_insert(int at, int entry_num) const +{ + SIMPLE_VOID_WRAPPER(queue_insert, at, entry_num); +} +EXPORT void Playlist::queue_insert_selected(int at) const +{ + SIMPLE_VOID_WRAPPER(queue_insert_selected, at); +} +EXPORT int Playlist::queue_get_entry(int at) const +{ + SIMPLE_WRAPPER(int, -1, queue_get_entry, at); +} +EXPORT int Playlist::queue_find_entry(int entry_num) const +{ + SIMPLE_WRAPPER(int, -1, queue_find_entry, entry_num); +} +EXPORT void Playlist::queue_remove(int at, int number) const +{ + SIMPLE_VOID_WRAPPER(queue_remove, at, number); +} +EXPORT void Playlist::queue_remove_selected() const +{ + SIMPLE_VOID_WRAPPER(queue_remove_selected); +} + +EXPORT bool Playlist::update_pending() const +{ + SIMPLE_WRAPPER(bool, false, update_pending); +} +EXPORT Playlist::Update Playlist::update_detail() const +{ + SIMPLE_WRAPPER(Update, Update(), last_update); +} + +void PlaylistEx::insert_flat_items(int at, + Index<PlaylistAddItem> && items) const +{ + SIMPLE_VOID_WRAPPER(insert_items, at, std::move(items)); +} + +EXPORT int Playlist::index() const +{ + ENTER_GET_PLAYLIST(-1); + return m_id->index; +} + +EXPORT int PlaylistEx::stamp() const +{ + ENTER_GET_PLAYLIST(-1); + return m_id->stamp; +} + +EXPORT int Playlist::n_playlists() +{ + auto mh = mutex.take(); + return playlists.len(); +} + +EXPORT Playlist Playlist::by_index(int at) +{ + auto mh = mutex.take(); + Playlist::ID * id = + (at >= 0 && at < playlists.len()) ? playlists[at]->id() : nullptr; + return Playlist(id); +} + +static Playlist::ID * insert_playlist_locked(int at, int stamp = -1) +{ + if (at < 0 || at > playlists.len()) + at = playlists.len(); + + auto id = create_playlist(stamp); + + playlists.insert(at, 1); + playlists[at].capture(id->data); + + number_playlists(at, playlists.len() - at); + + /* this will only happen at startup */ + if (!active_id) + active_id = id; + + queue_global_update(Playlist::Structure); + + return id; +} + +static Playlist::ID * get_blank_locked() +{ + if (!strcmp(active_id->data->title, _(default_title)) && + !active_id->data->n_entries()) + return active_id; + + return insert_playlist_locked(active_id->index + 1); +} + +Playlist PlaylistEx::insert_with_stamp(int at, int stamp) +{ + auto mh = mutex.take(); + auto id = insert_playlist_locked(at, stamp); + return Playlist(id); +} + +EXPORT Playlist Playlist::insert_playlist(int at) +{ + auto mh = mutex.take(); + auto id = insert_playlist_locked(at); + return Playlist(id); +} + +EXPORT void Playlist::reorder_playlists(int from, int to, int count) +{ + auto mh = mutex.take(); + + if (from < 0 || from + count > playlists.len() || to < 0 || + to + count > playlists.len() || count < 0) + return; + + Index<SmartPtr<PlaylistData>> displaced; + + if (to < from) + displaced.move_from(playlists, to, -1, from - to, true, false); + else + displaced.move_from(playlists, from + count, -1, to - from, true, + false); + + playlists.shift(from, to, count); + + if (to < from) + { + playlists.move_from(displaced, 0, to + count, from - to, false, true); + number_playlists(to, from + count - to); + } + else + { + playlists.move_from(displaced, 0, from, to - from, false, true); + number_playlists(from, to + count - from); + } + + queue_global_update(Structure); +} + +EXPORT void Playlist::remove_playlist() const +{ + ENTER_GET_PLAYLIST(); + + int at = m_id->index; + playlists.remove(at, 1); + + if (!playlists.len()) + playlists.append(create_playlist(-1)->data); + + number_playlists(at, playlists.len() - at); + + if (m_id == active_id) + { + int active_num = aud::min(at, playlists.len() - 1); + active_id = playlists[active_num]->id(); + queue_update_hooks(SetActive); + } + + if (m_id == playing_id) + { + playing_id = nullptr; + stop_playback_locked(); + queue_update_hooks(SetPlaying | PlaybackStop); + } + + queue_global_update(Structure); +} + +EXPORT void Playlist::set_filename(const char * filename) const +{ + ENTER_GET_PLAYLIST(); + + playlist->filename = String(filename); + playlist->modified = true; + + queue_global_update(Metadata); +} + +EXPORT String Playlist::get_filename() const +{ + ENTER_GET_PLAYLIST(String()); + return playlist->filename; +} + +EXPORT void Playlist::set_title(const char * title) const +{ + ENTER_GET_PLAYLIST(); + + playlist->title = String(title); + playlist->modified = true; + + queue_global_update(Metadata); +} + +EXPORT String Playlist::get_title() const +{ + ENTER_GET_PLAYLIST(String()); + return playlist->title; +} + +void PlaylistEx::set_modified(bool modified) const +{ + ENTER_GET_PLAYLIST(); + playlist->modified = modified; +} + +bool PlaylistEx::get_modified() const +{ + ENTER_GET_PLAYLIST(false); + return playlist->modified; +} + +EXPORT void Playlist::activate() const +{ + ENTER_GET_PLAYLIST(); + + if (m_id != active_id) + { + active_id = m_id; + queue_update_hooks(SetActive); + } +} + +EXPORT Playlist Playlist::active_playlist() +{ + auto mh = mutex.take(); + return Playlist(active_id); +} + +EXPORT Playlist Playlist::new_playlist() +{ + auto mh = mutex.take(); + + int at = active_id->index + 1; + auto id = insert_playlist_locked(at); + + active_id = id; + queue_update_hooks(SetActive); + + return Playlist(id); +} + +static void set_playing_locked(Playlist::ID * id, bool paused) +{ + if (id == playing_id) + { + /* already playing, just need to pause/unpause */ + if (aud_drct_get_paused() != paused) + aud_drct_pause(); + + return; + } + + if (playing_id) + playing_id->data->resume_time = aud_drct_get_time(); + + /* is there anything to play? */ + if (id && id->data->position() < 0 && !id->data->next_song(true)) + id = nullptr; + + playing_id = id; + + if (id) + { + start_playback_locked(id->data->resume_time, paused); + queue_update_hooks(SetPlaying | PlaybackBegin); + } + else + { + stop_playback_locked(); + queue_update_hooks(SetPlaying | PlaybackStop); + } +} + +EXPORT void Playlist::start_playback(bool paused) const +{ + ENTER_GET_PLAYLIST(); + set_playing_locked(m_id, paused); +} + +EXPORT void aud_drct_stop() +{ + auto mh = mutex.take(); + set_playing_locked(nullptr, false); +} + +EXPORT Playlist Playlist::playing_playlist() +{ + auto mh = mutex.take(); + return Playlist(playing_id); +} + +EXPORT Playlist Playlist::blank_playlist() +{ + auto mh = mutex.take(); + auto id = get_blank_locked(); + return Playlist(id); +} + +EXPORT Playlist Playlist::temporary_playlist() +{ + auto mh = mutex.take(); + + const char * title = _(temp_title); + ID * id = nullptr; + + for (auto & playlist : playlists) + { + if (!strcmp(playlist->title, title)) + { + id = playlist->id(); + break; + } + } + + if (!id) + { + id = get_blank_locked(); + id->data->title = String(title); + } + + return Playlist(id); +} + +EXPORT PluginHandle * Playlist::entry_decoder(int entry_num, GetMode mode, + String * error) const +{ + ENTER_GET_PLAYLIST(nullptr); + wait_for_entry(mh, playlist, entry_num, (mode == Wait), false); + return playlist->entry_decoder(entry_num, error); +} + +EXPORT Tuple Playlist::entry_tuple(int entry_num, GetMode mode, + String * error) const +{ + ENTER_GET_PLAYLIST(Tuple()); + wait_for_entry(mh, playlist, entry_num, false, (mode == Wait)); + return playlist->entry_tuple(entry_num, error); +} + +EXPORT void Playlist::rescan_file(const char * filename) +{ + auto mh = mutex.take(); + + for (auto & playlist : playlists) + playlist->reset_tuple_of_file(filename); +} + +// called from playback thread +DecodeInfo playback_entry_read(int serial) +{ + auto mh = mutex.take(); + DecodeInfo dec; + + if (playback_check_serial(serial)) + { + auto playlist = playing_id->data; + auto entry = playlist->entry_at(playlist->position()); + + ScanItem * item = scan_list_find_entry(entry); + assert(item && item->for_playback); + + ScanRequest * request = item->request; + item->handled_by_playback = true; + + mh.unlock(); + request->run(); + mh.lock(); + + if (playback_check_serial(serial)) + { + assert(playlist == playing_id->data); + + int pos = playlist->position(); + playback_set_info(pos, playlist->entry_tuple(pos)); + + art_cache_current(request->filename, std::move(request->image_data), + std::move(request->image_file)); + + dec.filename = request->filename; + dec.ip = request->ip; + dec.file = std::move(request->file); + dec.error = std::move(request->error); + } + + delete request; + } + + return dec; +} + +// called from playback thread +void playback_entry_set_tuple(int serial, Tuple && tuple) +{ + auto mh = mutex.take(); + + if (playback_check_serial(serial)) + playing_id->data->update_playback_entry(std::move(tuple)); +} + +void playlist_save_state() +{ + /* get playback state before locking playlists */ + bool paused = aud_drct_get_paused(); + int time = aud_drct_get_time(); + + auto mh = mutex.take(); + + const char * user_dir = aud_get_path(AudPath::UserDir); + StringBuf path = filename_build({user_dir, STATE_FILE}); + + FILE * handle = g_fopen(path, "w"); + if (!handle) + return; + + fprintf(handle, "active %d\n", active_id ? active_id->index : -1); + fprintf(handle, "playing %d\n", playing_id ? playing_id->index : -1); + + for (auto & playlist : playlists) + { + fprintf(handle, "playlist %d\n", playlist->id()->index); + + if (playlist->filename) + fprintf(handle, "filename %s\n", (const char *)playlist->filename); + + fprintf(handle, "position %d\n", playlist->position()); + + /* save shuffle history */ + auto history = playlist->shuffle_history(); + + for (int i = 0; i < history.len(); i += 16) + { + int count = aud::min(16, history.len() - i); + auto list = int_array_to_str(&history[i], count); + fprintf(handle, "shuffle %s\n", (const char *)list); + } + + /* resume state is stored per-playlist for historical reasons */ + bool is_playing = (playlist->id() == playing_id); + fprintf(handle, "resume-state %d\n", + (is_playing && paused) ? ResumePause : ResumePlay); + fprintf(handle, "resume-time %d\n", + is_playing ? time : playlist->resume_time); + } + + fclose(handle); +} + +void playlist_load_state() +{ + auto mh = mutex.take(); + int playlist_num; + + const char * user_dir = aud_get_path(AudPath::UserDir); + StringBuf path = filename_build({user_dir, STATE_FILE}); + + FILE * handle = g_fopen(path, "r"); + if (!handle) + return; + + TextParser parser(handle); + + if (parser.get_int("active", playlist_num)) + { + if (playlist_num >= 0 && playlist_num < playlists.len()) + active_id = playlists[playlist_num]->id(); + + parser.next(); + } + + if (parser.get_int("playing", resume_playlist)) + parser.next(); + + while (parser.get_int("playlist", playlist_num) && playlist_num >= 0 && + playlist_num < playlists.len()) + { + PlaylistData * playlist = playlists[playlist_num].get(); + + parser.next(); + + playlist->filename = parser.get_str("filename"); + if (playlist->filename) + parser.next(); + + int position = -1; + if (parser.get_int("position", position)) + { + playlist->set_position(position); + parser.next(); + } + + /* restore shuffle history */ + Index<int> history; + + for (String list; (list = parser.get_str("shuffle")); parser.next()) + { + auto split = str_list_to_index(list, ", "); + for (auto & str : split) + history.append(str_to_int(str)); + } + + if (history.len()) + playlist->shuffle_replay(history); + + /* resume state is stored per-playlist for historical reasons */ + int resume_state = ResumePlay; + if (parser.get_int("resume-state", resume_state)) + parser.next(); + + if (playlist_num == resume_playlist) + { + if (resume_state == ResumeStop) + resume_playlist = -1; + if (resume_state == ResumePause) + resume_paused = true; + } + + if (parser.get_int("resume-time", playlist->resume_time)) + parser.next(); + } + + fclose(handle); + + /* set initial focus and selection */ + for (auto & playlist : playlists) + { + int focus = playlist->position(); + if (focus < 0 && playlist->n_entries()) + focus = 0; + + if (focus >= 0) + { + playlist->set_focus(focus); + playlist->select_entry(focus, true); + } + } +} + +EXPORT void aud_resume() +{ + if (aud_get_bool("always_resume_paused")) + resume_paused = true; + + Playlist::by_index(resume_playlist).start_playback(resume_paused); +} diff --git a/src/libaudcore/playlist.h b/src/libaudcore/playlist.h new file mode 100644 index 0000000..e88ec30 --- /dev/null +++ b/src/libaudcore/playlist.h @@ -0,0 +1,416 @@ +/* + * playlist.h + * Copyright 2010-2017 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_PLAYLIST_H +#define LIBAUDCORE_PLAYLIST_H + +#include <stdint.h> + +#include <libaudcore/index.h> +#include <libaudcore/tuple.h> + +/* + * Persistent handle attached to a playlist. + * Follows the same playlist even if playlists are reordered. + * Does not prevent the playlist from being deleted (check exists()). + */ +class Playlist +{ +public: + /* --- TYPES --- */ + + /* Opaque type which uniquely identifies a playlist */ + struct ID; + + /* The values which can be passed to the "playlist update" hook. Selection + * means that entries have been selected or unselected, or that entries have + * been added to or removed from the queue. Metadata means that new + * metadata has been read for some entries, or that the title or filename of + * a playlist has changed, and implies Selection. Structure covers any + * other change, and implies both Selection and Metadata. */ + enum UpdateLevel + { + NoUpdate = 0, + Selection, + Metadata, + Structure + }; + + struct Update + { + UpdateLevel level; // type of update + int before; // number of unaffected entries at playlist start + int after; // number of unaffected entries at playlist end + bool queue_changed; // true if entries have been added to/removed from + // queue + }; + + /* Preset sorting "schemes" */ + enum SortType + { + Path, // entry's entire URI + Filename, // base name (no folder path) + Title, + Album, + Artist, + AlbumArtist, + Date, // release date (not modification time) + Genre, + Track, + FormattedTitle, + Length, + Comment, + n_sort_types + }; + + /* Possible behaviors for entry_{decoder, tuple}. */ + enum GetMode + { + NoWait, // non-blocking call; returned tuple will be in Initial state if + // not yet scanned + Wait // blocking call; returned tuple will be either Valid or Failed + }; + + /* Format descriptor returned by save_formats() */ + struct SaveFormat + { + String name; // human-readable format name + Index<String> exts; // supported filename extensions + }; + + typedef bool (*FilterFunc)(const char * filename, void * user); + typedef int (*StringCompareFunc)(const char * a, const char * b); + typedef int (*TupleCompareFunc)(const Tuple & a, const Tuple & b); + + /* --- CONSTRUCTOR ETC. --- */ + + /* Default constructor; indicates "no playlist" */ + constexpr Playlist() : m_id(nullptr) {} + + bool operator==(const Playlist & b) const { return m_id == b.m_id; } + bool operator!=(const Playlist & b) const { return m_id != b.m_id; } + + /* The number of the playlist in display order, starting from 0. + * Returns -1 if the playlist no longer exists. */ + int index() const; + + /* True if the playlist exists (i.e. has not been deleted). */ + bool exists() const { return index() >= 0; } + + /* --- CORE (STATIC) API --- */ + + /* Returns the number of playlists currently open (>= 1). */ + static int n_playlists(); + + /* Looks up a playlist by display order. */ + static Playlist by_index(int at); + + /* Adds a new playlist before the one numbered <at> (-1 = insert at end). */ + static Playlist insert_playlist(int at); + + /* Moves a contiguous block of <count> playlists starting with the one + * numbered <from> such that that playlist ends up at the position <to>. */ + static void reorder_playlists(int from, int to, int count); + + /* Returns the active (i.e. displayed) playlist. */ + static Playlist active_playlist(); + + /* Convenience function which adds a new playlist after the active one and + * then sets the new one as active. Returns the new playlist. */ + static Playlist new_playlist(); + + /* Returns the currently playing playlist. If no playlist is playing, + * returns Playlist(). */ + static Playlist playing_playlist(); + + /* Returns the number of a "blank" playlist. The active playlist is + * returned if it has the default title and has no entries; otherwise, a new + * playlist is added and returned. */ + static Playlist blank_playlist(); + + /* Returns the number of the "temporary" playlist (which is no different + * from any other playlist except in name). If the playlist does not exist, + * a "blank" playlist is renamed to become the temporary playlist. */ + static Playlist temporary_playlist(); + + /* Discards the metadata stored for all the entries that refer to a + * particular song file, in whatever playlist they appear, and starts + * reading it afresh from that file in the background. */ + static void rescan_file(const char * filename); + + /* --- CORE (NON-STATIC) API --- */ + + /* Gets/sets the filename associated with this playlist. + * (Audacious currently makes no use of the filename.) */ + String get_filename() const; + void set_filename(const char * filename) const; + + /* Gets/sets the title of the playlist. */ + String get_title() const; + void set_title(const char * title) const; + + /* Closes the playlist. + * The playlist is not saved, and no confirmation is presented to the user. + * When the last playlist is closed, a new one is added in its place. + * When the active playlist is closed, another is made active. + * When the playing playlist is closed, playback stops. */ + void remove_playlist() const; + + /* Makes this the active (i.e. displayed) playlist. */ + void activate() const; + + /* Starts playback of this playlist, unless it is empty. + * Resumes from the position last played if possible. + * If <paused> is true, starts playback in a paused state. */ + void start_playback(bool paused = false) const; + + /* Returns the number of entries (numbered from 0). */ + int n_entries() const; + + /* Adds a single song file, playlist file, or folder before the entry <at>. + * If <at> is negative or equal to the number of entries, the item is added + * after the last entry. <tuple> may be null, in which case Audacious will + * attempt to read metadata from the song file. If <play> is true, + * Audacious will begin playback of the items once they have been added. + * + * This function is asynchronous (the items are added in the background). */ + void insert_entry(int at, const char * filename, Tuple && tuple, + bool play) const; + + /* Adds multiple song files, playlist files, or folders to a playlist. */ + void insert_items(int at, Index<PlaylistAddItem> && items, bool play) const; + + /* Similar to insert_items() but allows the caller to prevent some items + * from being added by returning false from the <filter> callback. Useful + * for searching a folder and adding only new files to the playlist. <user> + * is an opaque pointer passed to the callback. */ + void insert_filtered(int at, Index<PlaylistAddItem> && items, + FilterFunc filter, void * user, bool play) const; + + /* Removes entries from the playlist. The playback position may be moved, + * or playback may be stopped (according to user preference). */ + void remove_entries(int at, int number) const; + void remove_entry(int at) const { remove_entries(at, 1); } + void remove_all_entries() const { remove_entries(0, -1); } + + /* Returns an entry's filename. */ + String entry_filename(int entry) const; + + /* Returns an entry's decoder plugin. On error, or if the entry has not yet + * been scanned, returns nullptr according to <mode>. An optional error + * message may be returned. */ + PluginHandle * entry_decoder(int entry, GetMode mode = Wait, + String * error = nullptr) const; + + /* Returns an entry's metadata. The state of the returned tuple may + * indicate that the entry has not yet been scanned, or an error occurred, + * according to <mode>. An optional error message may be returned. */ + Tuple entry_tuple(int entry, GetMode mode = Wait, + String * error = nullptr) const; + + /* Gets/sets the playing or last-played entry (-1 = no entry). + * Affects playback only if this playlist is currently playing. + * set_position(get_position()) restarts playback from 0:00. + * set_position(-1) stops playback. */ + int get_position() const; + void set_position(int position) const; + + /* Advances the playlist position to the next entry in playback order, + * taking current shuffle settings into account. At the end of the + * playlist, wraps around to the beginning if <repeat> is true. Returns + * true on success, false if playlist position was not changed. */ + bool next_song(bool repeat) const; + + /* Advances the playlist position to the first entry of the next album in + * playback order, taking current shuffle settings into account. At the + * end of the playlist, wraps around to the beginning if <repeat> is true. + * Returns true on success, false if playlist position was not changed. */ + bool next_album(bool repeat) const; + + /* Returns the playlist position to the previous entry in playback order. + * Does not support wrapping past the beginning of the playlist. Returns + * true on success, false if playlist position was not changed. */ + bool prev_song() const; + + /* Returns the playlist position to the first entry in playback order where + * the album is not the current album. Does not support wrapping past the + * beginning of the playlist. Returns true on success, false if playlist + * position was not changed. */ + bool prev_album() const; + + /* Gets/sets the entry which has keyboard focus (-1 = no entry). */ + int get_focus() const; + void set_focus(int entry) const; + + /* Gets/sets whether an entry is selected. */ + bool entry_selected(int entry) const; + void select_entry(int entry, bool selected) const; + + /* Returns the number of selected entries. + * An optional range of entries to examine may be specified. */ + int n_selected(int at = 0, int number = -1) const; + + /* Selects all (or none) of the entries in a playlist. */ + void select_all(bool selected) const; + + /* Moves a selected entry within a playlist by an offset of <distance> + * entries. Other selected entries are gathered around it. Returns the + * offset by which the entry was actually moved (which may be less than the + * requested offset. */ + int shift_entries(int position, int distance) const; + + /* Removes all selected entries. */ + void remove_selected() const; + + /* Sorts the entries in a playlist based on filename. The callback function + * should return negative if the first filename comes before the second, + * positive if it comes after, or zero if the two are indistinguishable. */ + void sort_by_filename(StringCompareFunc compare) const; + + /* Sorts the entries in a playlist based on tuple. May fail if metadata + * scanning is still in progress (or has been disabled). */ + void sort_by_tuple(TupleCompareFunc compare) const; + + /* Sorts the entries in a playlist based on formatted title string. May + * fail if metadata scanning is still in progress (or has been disabled). */ + void sort_by_title(StringCompareFunc compare) const; + + /* Sorts only the selected entries in a playlist based on filename. */ + void sort_selected_by_filename(StringCompareFunc compare) const; + + /* Sorts only the selected entries in a playlist based on tuple. May fail + * if metadata scanning is still in progress (or has been disabled). */ + void sort_selected_by_tuple(TupleCompareFunc compare) const; + + /* Sorts only the selected entries in a playlist based on formatted title + * string. May fail if metadata scanning is still in progress (or has been + * disabled). */ + void sort_selected_by_title(StringCompareFunc compare) const; + + /* Reverses the order of the entries in a playlist. */ + void reverse_order() const; + + /* Reorders the entries in a playlist randomly. */ + void randomize_order() const; + + /* Reverses the order of the selected entries in a playlist. */ + void reverse_selected() const; + + /* Reorders the selected entries in a playlist randomly. */ + void randomize_selected() const; + + /* Discards the metadata stored for entries in a playlist and starts reading + * it fresh from the song files in the background. */ + void rescan_all() const; + void rescan_selected() const; + + /* Calculates the length in milliseconds of entries in a playlist. Only + * takes into account entries for which metadata has already been read. */ + int64_t total_length_ms() const; + int64_t selected_length_ms() const; + + /* Returns the number of entries in a playlist queue. */ + int n_queued() const; + + /* Adds an entry to the queue at <pos> (-1 = at end of queue). + * The same entry cannot be added to the queue more than once. */ + void queue_insert(int pos, int entry) const; + void queue_insert_selected(int pos) const; + + /* Returns the entry at the given queue position. */ + int queue_get_entry(int pos) const; + + /* Returns the queue position of the given entry (-1 if not queued). */ + int queue_find_entry(int entry) const; + + /* Removes entries from the queue. */ + void queue_remove(int pos, int number = 1) const; + void queue_remove_all() const { queue_remove(0, -1); } + + /* Removes the selected entries in a playlist from the queue, if they are in + * it. */ + void queue_remove_selected() const; + + /* Returns true if a "playlist update" hook call is pending. + * A running hook call is not considered pending. */ + bool update_pending() const; + static bool update_pending_any(); + + /* Immediately calls any pending "playlist update" hook. Use cautiously. */ + static void process_pending_update(); + + /* May be called within the "playlist update" hook to determine the update + * level and number of entries changed in a playlist. */ + Update update_detail() const; + + /* Returns true if entries are being added in the background. */ + bool add_in_progress() const; + static bool add_in_progress_any(); + + /* Returns true if entries are being scanned in the background. */ + bool scan_in_progress() const; + static bool scan_in_progress_any(); + + /* --- UTILITY API --- */ + + /* Sorts entries according to a preset scheme. */ + void sort_entries(SortType scheme) const; + void sort_selected(SortType scheme) const; + + /* Removes duplicate entries according to a preset scheme. + * The current implementation also sorts the playlist. */ + void remove_duplicates(SortType scheme) const; + + /* Removes all entries referring to inaccessible files in a playlist. */ + void remove_unavailable() const; + + /* Selects entries by matching regular expressions. + * Example: To select all titles starting with the letter "A", + * create a blank tuple and set its title field to "^A". */ + void select_by_patterns(const Tuple & patterns) const; + + /* Saves metadata for the selected entries to an internal cache. + * This will speed up adding those entries to another playlist. */ + void cache_selected() const; + + /* Saves the entries in a playlist to a playlist file. + * The format of the file is determined from the file extension. + * <mode> specifies whether to wait for metadata scanning to complete. + * Returns true on success. */ + bool save_to_file(const char * filename, GetMode mode) const; + + /* Checks a filename for an extension matching a known playlist format. */ + static bool filename_is_playlist(const char * filename); + + /* Generates a list of the currently supported formats for saving playlists. + * The list should not be cached since it may change as plugins are enabled + * or disabled. */ + static Index<SaveFormat> save_formats(); + + /* --- IMPLEMENTATION --- */ + +private: + ID * m_id; + + explicit constexpr Playlist(ID * id) : m_id(id) {} + + friend class PlaylistEx; +}; + +#endif diff --git a/src/libaudcore/plugin-init.cc b/src/libaudcore/plugin-init.cc new file mode 100644 index 0000000..5d2ae39 --- /dev/null +++ b/src/libaudcore/plugin-init.cc @@ -0,0 +1,401 @@ +/* + * plugin-init.c + * Copyright 2010-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "plugins-internal.h" + +#include <assert.h> +#include <stdlib.h> + +#include "hook.h" +#include "interface.h" +#include "internal.h" +#include "output.h" +#include "plugin.h" +#include "runtime.h" + +static bool general_plugin_start(PluginHandle * plugin) +{ + auto gp = (GeneralPlugin *)aud_plugin_get_header(plugin); + return gp && gp->init(); +} + +void general_plugin_stop(PluginHandle * plugin) +{ + GeneralPlugin * gp = (GeneralPlugin *)aud_plugin_get_header(plugin); + if (gp) + gp->cleanup(); +} + +struct MultiFuncs +{ + bool (*start)(PluginHandle * plugin); + void (*stop)(PluginHandle * plugin); +}; + +struct SingleFuncs +{ + PluginHandle * (*get_current)(); + bool (*set_current)(PluginHandle * plugin); +}; + +union PluginFuncs { + MultiFuncs m; + SingleFuncs s; + + constexpr PluginFuncs(MultiFuncs multi) : m(multi) {} + constexpr PluginFuncs(SingleFuncs single) : s(single) {} +}; + +struct PluginParams +{ + const char * name; + bool is_single; + PluginFuncs f; + + constexpr PluginParams(const char * name, MultiFuncs multi) + : name(name), is_single(false), f(multi) + { + } + constexpr PluginParams(const char * name, SingleFuncs single) + : name(name), is_single(true), f(single) + { + } +}; + +static constexpr aud::array<PluginType, PluginParams> table = { + PluginParams("transport", MultiFuncs({nullptr, nullptr})), + PluginParams("playlist", MultiFuncs({nullptr, nullptr})), + PluginParams("input", MultiFuncs({nullptr, nullptr})), + PluginParams("effect", + MultiFuncs({effect_plugin_start, effect_plugin_stop})), + PluginParams("output", SingleFuncs({output_plugin_get_current, + output_plugin_set_current})), + PluginParams("visualization", + MultiFuncs({vis_plugin_start, vis_plugin_stop})), + PluginParams("general", + MultiFuncs({general_plugin_start, general_plugin_stop})), + PluginParams("interface", SingleFuncs({iface_plugin_get_current, + iface_plugin_set_current}))}; + +static bool start_plugin(PluginType type, PluginHandle * p, + bool secondary = false) +{ + bool success; + + if (secondary) + success = output_plugin_set_secondary(p); + else if (table[type].is_single) + success = table[type].f.s.set_current(p); + else + success = table[type].f.m.start(p); + + if (!success) + { + AUDWARN("%s failed to start.\n", aud_plugin_get_name(p)); + plugin_set_failed(p); + } + + return success; +} + +static PluginHandle * find_selected(PluginType type, PluginEnabled enabled) +{ + for (PluginHandle * p : aud_plugin_list(type)) + { + if (plugin_get_enabled(p) == enabled) + return p; + } + + return nullptr; +} + +static void start_required(PluginType type) +{ + PluginHandle * sel; + if ((sel = find_selected(type, PluginEnabled::Primary))) + { + AUDINFO("Starting selected %s plugin %s.\n", table[type].name, + aud_plugin_get_name(sel)); + + if (start_plugin(type, sel)) + return; + } + + AUDINFO("Probing for %s plugin.\n", table[type].name); + + for (PluginHandle * p : aud_plugin_list(type)) + { + if (p == sel) + continue; + + AUDINFO("Trying to start %s.\n", aud_plugin_get_name(p)); + plugin_set_enabled(p, PluginEnabled::Primary); + + if (start_plugin(type, p)) + return; + } + + AUDERR("No %s plugin found.\n" + "(Did you forget to install audacious-plugins?)\n", + table[type].name); + abort(); +} + +static void start_plugins(PluginType type) +{ + /* no interface plugin in headless mode */ + if (type == PluginType::Iface && aud_get_headless_mode()) + return; + + if (table[type].is_single) + { + start_required(type); + + if (type == PluginType::Output) + { + PluginHandle * sel; + if ((sel = find_selected(type, PluginEnabled::Secondary))) + { + AUDINFO("Starting secondary output plugin %s.\n", + aud_plugin_get_name(sel)); + start_plugin(type, sel, true); + } + } + } + else if (table[type].f.m.start) + { + for (PluginHandle * p : aud_plugin_list(type)) + { + if (aud_plugin_get_enabled(p)) + { + AUDINFO("Starting %s.\n", aud_plugin_get_name(p)); + start_plugin(type, p); + } + } + } +} + +void start_plugins_one() +{ + plugin_system_init(); + + start_plugins(PluginType::Transport); + start_plugins(PluginType::Playlist); + start_plugins(PluginType::Input); + start_plugins(PluginType::Effect); + start_plugins(PluginType::Output); +} + +void start_plugins_two() +{ + start_plugins(PluginType::Vis); + start_plugins(PluginType::General); + start_plugins(PluginType::Iface); +} + +static void stop_plugins(PluginType type) +{ + if (table[type].is_single) + { + PluginHandle * p = table[type].f.s.get_current(); + AUDINFO("Shutting down %s.\n", aud_plugin_get_name(p)); + table[type].f.s.set_current(nullptr); + + if (type == PluginType::Output && (p = output_plugin_get_secondary())) + { + AUDINFO("Shutting down %s.\n", aud_plugin_get_name(p)); + output_plugin_set_secondary(nullptr); + } + } + else if (table[type].f.m.stop) + { + for (PluginHandle * p : aud_plugin_list(type)) + { + if (aud_plugin_get_enabled(p)) + { + AUDINFO("Shutting down %s.\n", aud_plugin_get_name(p)); + table[type].f.m.stop(p); + } + } + } +} + +void stop_plugins_two() +{ + /* interface plugin is already shut down */ + stop_plugins(PluginType::General); + stop_plugins(PluginType::Vis); +} + +void stop_plugins_one() +{ + stop_plugins(PluginType::Output); + stop_plugins(PluginType::Effect); + stop_plugins(PluginType::Input); + stop_plugins(PluginType::Playlist); + stop_plugins(PluginType::Transport); + + plugin_system_cleanup(); +} + +EXPORT PluginHandle * aud_plugin_get_current(PluginType type) +{ + assert(table[type].is_single); + return table[type].f.s.get_current(); +} + +static bool enable_single(PluginType type, PluginHandle * p) +{ + PluginHandle * old = table[type].f.s.get_current(); + + AUDINFO("Switching from %s to %s.\n", aud_plugin_get_name(old), + aud_plugin_get_name(p)); + + plugin_set_enabled(old, PluginEnabled::Disabled); + plugin_set_enabled(p, PluginEnabled::Primary); + + if (start_plugin(type, p)) + return true; + + AUDINFO("Falling back to %s.\n", aud_plugin_get_name(old)); + plugin_set_enabled(old, PluginEnabled::Primary); + + if (start_plugin(type, old)) + return false; + + abort(); +} + +static bool enable_multi(PluginType type, PluginHandle * p, bool enable) +{ + AUDINFO("%sabling %s.\n", enable ? "En" : "Dis", aud_plugin_get_name(p)); + + if (enable) + { + plugin_set_enabled(p, PluginEnabled::Primary); + + if (table[type].f.m.start && !start_plugin(type, p)) + return false; + + if (type == PluginType::Vis || type == PluginType::General) + hook_call("dock plugin enabled", p); + } + else + { + plugin_set_enabled(p, PluginEnabled::Disabled); + + if (type == PluginType::Vis || type == PluginType::General) + hook_call("dock plugin disabled", p); + + if (table[type].f.m.stop) + table[type].f.m.stop(p); + } + + return true; +} + +EXPORT bool aud_plugin_enable(PluginHandle * plugin, bool enable) +{ + PluginEnabled enabled = plugin_get_enabled(plugin); + if (enabled == (enable ? PluginEnabled::Primary : PluginEnabled::Disabled)) + return true; + + PluginType type = aud_plugin_get_type(plugin); + + if (table[type].is_single) + { + assert(enable); + return enable_single(type, plugin); + } + + return enable_multi(type, plugin, enable); +} + +bool plugin_enable_secondary(PluginHandle * plugin, bool enable) +{ + assert(aud_plugin_get_type(plugin) == PluginType::Output); + + PluginEnabled enabled = plugin_get_enabled(plugin); + assert(enabled != PluginEnabled::Primary); + + if (enabled == + (enable ? PluginEnabled::Secondary : PluginEnabled::Disabled)) + return true; + + if (enable) + { + PluginHandle * old; + if ((old = output_plugin_get_secondary())) + plugin_enable_secondary(old, false); + + AUDINFO("Enabling secondary output plugin %s.\n", + aud_plugin_get_name(plugin)); + plugin_set_enabled(plugin, PluginEnabled::Secondary); + return start_plugin(PluginType::Output, plugin, true); + } + else + { + AUDINFO("Disabling secondary output plugin %s.\n", + aud_plugin_get_name(plugin)); + plugin_set_enabled(plugin, PluginEnabled::Disabled); + output_plugin_set_secondary(nullptr); + return true; + } +} + +/* Miscellaneous plugin-related functions ... */ + +EXPORT int aud_plugin_send_message(PluginHandle * plugin, const char * code, + const void * data, int size) +{ + if (!aud_plugin_get_enabled(plugin)) + return -1; + + Plugin * header = (Plugin *)aud_plugin_get_header(plugin); + if (!header) + return -1; + + return header->take_message(code, data, size); +} + +EXPORT void * aud_plugin_get_gtk_widget(PluginHandle * plugin) +{ + if (!aud_plugin_get_enabled(plugin)) + return nullptr; + + PluginType type = aud_plugin_get_type(plugin); + if (type != PluginType::General && type != PluginType::Vis) + return nullptr; + + auto dp = (DockablePlugin *)aud_plugin_get_header(plugin); + return dp ? dp->get_gtk_widget() : nullptr; +} + +EXPORT void * aud_plugin_get_qt_widget(PluginHandle * plugin) +{ + if (!aud_plugin_get_enabled(plugin)) + return nullptr; + + PluginType type = aud_plugin_get_type(plugin); + if (type != PluginType::General && type != PluginType::Vis) + return nullptr; + + auto dp = (DockablePlugin *)aud_plugin_get_header(plugin); + return dp ? dp->get_qt_widget() : nullptr; +} diff --git a/src/libaudcore/plugin-load.cc b/src/libaudcore/plugin-load.cc new file mode 100644 index 0000000..cf3953e --- /dev/null +++ b/src/libaudcore/plugin-load.cc @@ -0,0 +1,177 @@ +/* + * plugin-load.cc + * Copyright 2007-2013 Ariadne Conill and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "plugins-internal.h" + +#include <assert.h> +#include <errno.h> +#include <string.h> +#include <sys/stat.h> + +#include <glib/gstdio.h> +#include <gmodule.h> + +#include "audstrings.h" +#include "internal.h" +#include "plugin.h" +#include "runtime.h" + +static const char * plugin_dir_list[] = {"Transport", "Container", "Input", + "Output", "Effect", "General", + "Visualization"}; + +struct LoadedModule +{ + Plugin * header; + GModule * module; +}; + +static Index<LoadedModule> loaded_modules; + +bool plugin_check_flags(int flags) +{ + switch (aud_get_mainloop_type()) + { + case MainloopType::GLib: + flags &= ~PluginGLibOnly; + break; + case MainloopType::Qt: + flags &= ~PluginQtOnly; + break; + } + + return !flags; +} + +Plugin * plugin_load(const char * filename) +{ + AUDINFO("Loading plugin: %s.\n", filename); + + GModule * module = g_module_open(filename, G_MODULE_BIND_LOCAL); + + if (!module) + { + AUDERR("%s could not be loaded: %s\n", filename, g_module_error()); + return nullptr; + } + + Plugin * header; + if (!g_module_symbol(module, "aud_plugin_instance", (void **)&header)) + header = nullptr; + + if (!header || header->magic != _AUD_PLUGIN_MAGIC) + { + AUDERR("%s is not a valid Audacious plugin.\n", filename); + g_module_close(module); + return nullptr; + } + + if (header->version < _AUD_PLUGIN_VERSION_MIN || + header->version > _AUD_PLUGIN_VERSION) + { + AUDERR("%s is not compatible with this version of Audacious.\n", + filename); + g_module_close(module); + return nullptr; + } + + if (plugin_check_flags(header->info.flags) && + (header->type == PluginType::Transport || + header->type == PluginType::Playlist || + header->type == PluginType::Input || + header->type == PluginType::Effect)) + { + if (!header->init()) + { + AUDERR("%s failed to initialize.\n", filename); + g_module_close(module); + return nullptr; + } + } + + loaded_modules.append(header, module); + + return header; +} + +static void plugin_unload(LoadedModule & loaded) +{ + if (plugin_check_flags(loaded.header->info.flags) && + (loaded.header->type == PluginType::Transport || + loaded.header->type == PluginType::Playlist || + loaded.header->type == PluginType::Input || + loaded.header->type == PluginType::Effect)) + { + loaded.header->cleanup(); + } + +#ifndef VALGRIND_FRIENDLY + g_module_close(loaded.module); +#endif +} + +/******************************************************************/ + +static bool scan_plugin_func(const char * path, const char * basename, + void * data) +{ + if (!str_has_suffix_nocase(basename, PLUGIN_SUFFIX)) + return false; + + GStatBuf st; + if (g_stat(path, &st) < 0) + { + AUDERR("Unable to stat %s: %s\n", path, strerror(errno)); + return false; + } + + if (S_ISREG(st.st_mode)) + plugin_register(path, st.st_mtime); + + return false; +} + +static void scan_plugins(const char * path) +{ + dir_foreach(path, scan_plugin_func, nullptr); +} + +void plugin_system_init() +{ + assert(g_module_supported()); + + plugin_registry_load(); + + const char * path = aud_get_path(AudPath::PluginDir); + for (const char * dir : plugin_dir_list) + scan_plugins(filename_build({path, dir})); + + plugin_registry_prune(); +} + +void plugin_system_cleanup() +{ + plugin_registry_save(); + plugin_registry_cleanup(); + + for (LoadedModule & loaded : loaded_modules) + plugin_unload(loaded); + + loaded_modules.clear(); +} diff --git a/src/libaudcore/plugin-registry.cc b/src/libaudcore/plugin-registry.cc new file mode 100644 index 0000000..47ce8dc --- /dev/null +++ b/src/libaudcore/plugin-registry.cc @@ -0,0 +1,776 @@ +/* + * plugin-registry.c + * Copyright 2009-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "plugins-internal.h" + +#include <errno.h> +#include <string.h> + +#include <glib/gstdio.h> + +#include "audstrings.h" +#include "i18n.h" +#include "interface.h" +#include "parse.h" +#include "plugin.h" +#include "runtime.h" +#include "threads.h" + +#define FILENAME "plugin-registry" + +/* Increment this when the format of the plugin-registry file changes. + * Add 10 if the format changes in a way that will break + * parse_plugins_fallback(). */ +#define FORMAT 11 + +/* Oldest file format supported by parse_plugins_fallback() */ +#define MIN_FORMAT 2 // "enabled" flag was added in Audacious 2.4 + +struct PluginWatch +{ + PluginWatchFunc func; + void * data; +}; + +class PluginHandle +{ +public: + String basename, path; + bool loaded; + int timestamp, version, flags; + PluginType type; + Plugin * header; + String name, domain; + int priority; + int has_about, has_configure; + PluginEnabled enabled; + Index<PluginWatch> watches; + + /* for transport plugins */ + Index<String> schemes; + + /* for playlist plugins */ + Index<String> exts; + int can_save; + + /* for input plugins */ + aud::array<InputKey, Index<String>> keys; + int has_subtunes, writes_tag; + + PluginHandle(const char * basename, const char * path, bool loaded, + int timestamp, int version, int flags, PluginType type, + Plugin * header) + : basename(basename), path(path), loaded(loaded), timestamp(timestamp), + version(version), flags(flags), type(type), header(header), + priority(0), has_about(false), has_configure(false), + enabled((type == PluginType::Transport || + type == PluginType::Playlist || type == PluginType::Input) + ? PluginEnabled::Primary + : PluginEnabled::Disabled), + can_save(false), has_subtunes(false), writes_tag(false) + { + } + + ~PluginHandle() + { + if (watches.len()) + AUDWARN("Plugin watch count not zero at exit!\n"); + } +}; + +static constexpr aud::array<PluginType, const char *> plugin_type_names = { + "transport", "playlist", "input", "effect", + "output", "vis", "general", "iface"}; + +static constexpr aud::array<InputKey, const char *> input_key_names = { + "scheme", "ext", "mime"}; + +static aud::array<PluginType, Index<PluginHandle *>> plugins; +static aud::array<PluginType, Index<PluginHandle *>> compatible; +static aud::mutex mutex; +static bool modified = false; + +static StringBuf get_basename(const char * path) +{ + const char * slash = strrchr(path, G_DIR_SEPARATOR); + const char * dot = slash ? strrchr(slash + 1, '.') : nullptr; + + return dot ? str_copy(slash + 1, dot - (slash + 1)) : StringBuf(); +} + +static FILE * open_registry_file(const char * mode) +{ + StringBuf path = filename_build({aud_get_path(AudPath::UserDir), FILENAME}); + FILE * handle = g_fopen(path, mode); + + if (!handle && errno != ENOENT) + AUDWARN("%s: %s\n", (const char *)path, strerror(errno)); + + return handle; +} + +static void transport_plugin_save(PluginHandle * plugin, FILE * handle) +{ + for (const String & scheme : plugin->schemes) + fprintf(handle, "scheme %s\n", (const char *)scheme); +} + +static void playlist_plugin_save(PluginHandle * plugin, FILE * handle) +{ + for (const String & ext : plugin->exts) + fprintf(handle, "ext %s\n", (const char *)ext); + + fprintf(handle, "saves %d\n", plugin->can_save); +} + +static void input_plugin_save(PluginHandle * plugin, FILE * handle) +{ + for (auto k : aud::range<InputKey>()) + { + for (const String & key : plugin->keys[k]) + fprintf(handle, "%s %s\n", input_key_names[k], (const char *)key); + } + + fprintf(handle, "subtunes %d\n", plugin->has_subtunes); + fprintf(handle, "writes %d\n", plugin->writes_tag); +} + +static void plugin_save(PluginHandle * plugin, FILE * handle) +{ + fprintf(handle, "%s %s\n", plugin_type_names[plugin->type], + (const char *)plugin->path); + fprintf(handle, "stamp %d\n", plugin->timestamp); + fprintf(handle, "version %d\n", plugin->version); + fprintf(handle, "flags %d\n", plugin->flags); + fprintf(handle, "name %s\n", (const char *)plugin->name); + + if (plugin->domain) + fprintf(handle, "domain %s\n", (const char *)plugin->domain); + + fprintf(handle, "priority %d\n", plugin->priority); + fprintf(handle, "about %d\n", plugin->has_about); + fprintf(handle, "config %d\n", plugin->has_configure); + fprintf(handle, "enabled %d\n", (int)plugin->enabled); + + if (plugin->type == PluginType::Transport) + transport_plugin_save(plugin, handle); + else if (plugin->type == PluginType::Playlist) + playlist_plugin_save(plugin, handle); + else if (plugin->type == PluginType::Input) + input_plugin_save(plugin, handle); +} + +void plugin_registry_save() +{ + if (!modified) + return; + + FILE * handle = open_registry_file("w"); + if (!handle) + return; + + fprintf(handle, "format %d\n", FORMAT); + + for (auto & list : plugins) + { + for (PluginHandle * plugin : list) + plugin_save(plugin, handle); + } + + fclose(handle); + modified = false; +} + +void plugin_registry_cleanup() +{ + for (auto & list : plugins) + { + for (PluginHandle * plugin : list) + delete plugin; + + list.clear(); + } + + for (auto & list : compatible) + list.clear(); +} + +static void transport_plugin_parse(PluginHandle * plugin, TextParser & parser) +{ + while (1) + { + String value = parser.get_str("scheme"); + if (!value) + break; + + plugin->schemes.append(std::move(value)); + parser.next(); + } +} + +static void playlist_plugin_parse(PluginHandle * plugin, TextParser & parser) +{ + while (1) + { + String value = parser.get_str("ext"); + if (!value) + break; + + plugin->exts.append(std::move(value)); + parser.next(); + } + + if (parser.get_int("saves", plugin->can_save)) + parser.next(); +} + +static void input_plugin_parse(PluginHandle * plugin, TextParser & parser) +{ + for (auto key : aud::range<InputKey>()) + { + while (1) + { + String value = parser.get_str(input_key_names[key]); + if (!value) + break; + + plugin->keys[key].append(std::move(value)); + parser.next(); + } + } + + if (parser.get_int("subtunes", plugin->has_subtunes)) + parser.next(); + if (parser.get_int("writes", plugin->writes_tag)) + parser.next(); +} + +static bool plugin_parse(TextParser & parser) +{ + PluginType type; + String path; + + for (auto type2 : aud::range<PluginType>()) + { + type = type2; + if ((path = parser.get_str(plugin_type_names[type2]))) + break; + } + + if (!path) + return false; + + StringBuf basename = get_basename(path); + if (!basename) + return false; + + parser.next(); + + int timestamp; + if (!parser.get_int("stamp", timestamp)) + return false; + + parser.next(); + + int version = 0, flags = 0; + if (parser.get_int("version", version)) + parser.next(); + if (parser.get_int("flags", flags)) + parser.next(); + + auto plugin = new PluginHandle(basename, String(), false, timestamp, + version, flags, type, nullptr); + + plugins[type].append(plugin); + + plugin->name = parser.get_str("name"); + if (plugin->name) + parser.next(); + + plugin->domain = parser.get_str("domain"); + if (plugin->domain) + parser.next(); + + if (parser.get_int("priority", plugin->priority)) + parser.next(); + if (parser.get_int("about", plugin->has_about)) + parser.next(); + if (parser.get_int("config", plugin->has_configure)) + parser.next(); + + int enabled; + if (parser.get_int("enabled", enabled)) + { + plugin->enabled = (PluginEnabled)enabled; + parser.next(); + } + + if (type == PluginType::Transport) + transport_plugin_parse(plugin, parser); + else if (type == PluginType::Playlist) + playlist_plugin_parse(plugin, parser); + else if (type == PluginType::Input) + input_plugin_parse(plugin, parser); + + return true; +} + +/* try to migrate enabled status from another version */ +static void parse_plugins_fallback(TextParser & parser) +{ + for (; !parser.eof(); parser.next()) + { + PluginType type; + String path; + int enabled; + + for (auto type2 : aud::range<PluginType>()) + { + type = type2; + if ((path = parser.get_str(plugin_type_names[type2]))) + break; + } + + if (!path) + continue; + + StringBuf basename = get_basename(path); + if (!basename) + continue; + + parser.next(); + + for (; !parser.eof(); parser.next()) + { + if (parser.get_int("enabled", enabled)) + break; + } + + if (parser.eof()) + return; + + // setting timestamp to zero forces a rescan + auto plugin = + new PluginHandle(basename, String(), false, 0, 0, 0, type, nullptr); + plugins[type].append(plugin); + plugin->enabled = (PluginEnabled)enabled; + } +} + +void plugin_registry_load() +{ + FILE * handle = open_registry_file("r"); + if (!handle) + return; + + TextParser parser(handle); + + int format; + if (!parser.get_int("format", format)) + goto ERR; + + parser.next(); + + if (format == FORMAT) + { + while (plugin_parse(parser)) + continue; + } + else if (format >= MIN_FORMAT && format < FORMAT + 10) + parse_plugins_fallback(parser); + +ERR: + fclose(handle); +} + +static int plugin_compare(PluginHandle * const & a, PluginHandle * const & b) +{ + if (a->type < b->type) + return -1; + if (a->type > b->type) + return 1; + if (a->priority < b->priority) + return -1; + if (a->priority > b->priority) + return 1; + + int diff; + if ((diff = str_compare(dgettext(a->domain, a->name), + dgettext(b->domain, b->name)))) + return diff; + + return str_compare(a->path, b->path); +} + +void plugin_registry_prune() +{ + auto check_not_found = [](PluginHandle * plugin) { + if (plugin->path) + return false; + + AUDINFO("Plugin not found: %s\n", (const char *)plugin->basename); + delete plugin; + return true; + }; + + auto check_incompatible = [](PluginHandle * plugin) { + if (plugin_check_flags(plugin->flags)) + return false; + + AUDINFO("Incompatible plugin flags: %s\n", + (const char *)plugin->basename); + return true; + }; + + for (auto type : aud::range<PluginType>()) + { + plugins[type].remove_if(check_not_found); + plugins[type].sort(plugin_compare); + compatible[type].insert(plugins[type].begin(), 0, plugins[type].len()); + compatible[type].remove_if(check_incompatible); + } +} + +/* Note: If there are multiple plugins with the same basename, this returns only + * one of them. Different plugins should be given different basenames. */ +static PluginHandle * plugin_lookup_basename(const char * basename, + bool compat_only) +{ + for (auto & list : (compat_only ? compatible : plugins)) + { + for (PluginHandle * plugin : list) + { + if (!strcmp(plugin->basename, basename)) + return plugin; + } + } + + return nullptr; +} + +EXPORT PluginHandle * aud_plugin_lookup_basename(const char * basename) +{ + return plugin_lookup_basename(basename, true); +} + +static void plugin_get_info(PluginHandle * plugin, bool is_new) +{ + Plugin * header = plugin->header; + + plugin->version = header->version; + plugin->flags = header->info.flags; + plugin->name = String(header->info.name); + plugin->domain = String(header->info.domain); + plugin->has_about = (bool)header->info.about; + plugin->has_configure = (bool)header->info.prefs; + + if (header->type == PluginType::Transport) + { + TransportPlugin * tp = (TransportPlugin *)header; + + plugin->schemes.clear(); + for (const char * scheme : tp->schemes) + plugin->schemes.append(String(scheme)); + } + else if (header->type == PluginType::Playlist) + { + PlaylistPlugin * pp = (PlaylistPlugin *)header; + + plugin->exts.clear(); + for (const char * ext : pp->extensions) + plugin->exts.append(String(ext)); + + plugin->can_save = pp->can_save; + } + else if (header->type == PluginType::Input) + { + InputPlugin * ip = (InputPlugin *)header; + plugin->priority = ip->input_info.priority; + + for (auto k : aud::range<InputKey>()) + { + plugin->keys[k].clear(); + for (auto key = ip->input_info.keys[k]; key && *key; key++) + plugin->keys[k].append(String(*key)); + } + + plugin->has_subtunes = + (ip->input_info.flags & InputPlugin::FlagSubtunes); + plugin->writes_tag = + (ip->input_info.flags & InputPlugin::FlagWritesTag); + } + else if (header->type == PluginType::Output) + { + OutputPlugin * op = (OutputPlugin *)header; + plugin->priority = 10 - op->priority; + } + else if (header->type == PluginType::Effect) + { + EffectPlugin * ep = (EffectPlugin *)header; + plugin->priority = ep->order; + } + else if (header->type == PluginType::General) + { + GeneralPlugin * gp = (GeneralPlugin *)header; + if (is_new && gp->enabled_by_default) + plugin->enabled = PluginEnabled::Primary; + } +} + +void plugin_register(const char * path, int timestamp) +{ + StringBuf basename = get_basename(path); + if (!basename) + return; + + PluginHandle * plugin = plugin_lookup_basename(basename, false); + + if (plugin) + { + AUDINFO("Register plugin: %s\n", path); + plugin->path = String(path); + + if (plugin->timestamp != timestamp) + { + AUDINFO("Rescan plugin: %s\n", path); + Plugin * header = plugin_load(path); + if (!header || header->type != plugin->type) + return; + + plugin->loaded = true; + plugin->header = header; + plugin->timestamp = timestamp; + + plugin_get_info(plugin, false); + modified = true; + } + } + else + { + AUDINFO("New plugin: %s\n", path); + Plugin * header = plugin_load(path); + if (!header) + return; + + plugin = + new PluginHandle(basename, path, true, timestamp, header->version, + header->info.flags, header->type, header); + plugins[plugin->type].append(plugin); + + plugin_get_info(plugin, true); + modified = true; + } +} + +EXPORT PluginType aud_plugin_get_type(PluginHandle * plugin) +{ + return plugin->type; +} + +EXPORT const char * aud_plugin_get_basename(PluginHandle * plugin) +{ + return plugin->basename; +} + +EXPORT const void * aud_plugin_get_header(PluginHandle * plugin) +{ + auto mh = mutex.take(); + + if (!plugin->loaded) + { + Plugin * header = plugin_load(plugin->path); + if (header && header->type == plugin->type) + plugin->header = header; + + plugin->loaded = true; + } + + return plugin->header; +} + +EXPORT PluginHandle * aud_plugin_by_header(const void * header) +{ + for (auto & list : compatible) + { + for (PluginHandle * plugin : list) + { + if (plugin->header == header) + return plugin; + } + } + + return nullptr; +} + +EXPORT const Index<PluginHandle *> & aud_plugin_list(PluginType type) +{ + return compatible[type]; +} + +EXPORT const char * aud_plugin_get_name(PluginHandle * plugin) +{ + return dgettext(plugin->domain, plugin->name); +} + +EXPORT bool aud_plugin_has_about(PluginHandle * plugin) +{ + return plugin->has_about; +} + +EXPORT bool aud_plugin_has_configure(PluginHandle * plugin) +{ + return plugin->has_configure; +} + +EXPORT bool aud_plugin_get_enabled(PluginHandle * plugin) +{ + return plugin->enabled != PluginEnabled::Disabled; +} + +static void plugin_call_watches(PluginHandle * plugin) +{ + auto call_and_check_remove = [=](const PluginWatch & watch) { + return !watch.func(plugin, watch.data); + }; + + plugin->watches.remove_if(call_and_check_remove); +} + +PluginEnabled plugin_get_enabled(PluginHandle * plugin) +{ + return plugin->enabled; +} + +void plugin_set_enabled(PluginHandle * plugin, PluginEnabled enabled) +{ + plugin->enabled = enabled; + plugin_call_watches(plugin); + modified = true; +} + +void plugin_set_failed(PluginHandle * plugin) +{ + plugin->header = nullptr; + plugin_set_enabled(plugin, PluginEnabled::Disabled); +} + +EXPORT void aud_plugin_add_watch(PluginHandle * plugin, PluginWatchFunc func, + void * data) +{ + plugin->watches.append(func, data); +} + +EXPORT void aud_plugin_remove_watch(PluginHandle * plugin, PluginWatchFunc func, + void * data) +{ + auto is_match = [=](const PluginWatch & watch) { + return watch.func == func && watch.data == data; + }; + + plugin->watches.remove_if(is_match); +} + +const Index<String> & transport_plugin_get_schemes(PluginHandle * plugin) +{ + return plugin->schemes; +} + +bool transport_plugin_has_scheme(PluginHandle * plugin, const char * scheme) +{ + for (String & s : plugin->schemes) + { + if (!strcmp(s, scheme)) + return true; + } + + return false; +} + +bool playlist_plugin_can_save(PluginHandle * plugin) +{ + return plugin->can_save; +} + +const Index<String> & playlist_plugin_get_exts(PluginHandle * plugin) +{ + return plugin->exts; +} + +bool playlist_plugin_has_ext(PluginHandle * plugin, const char * ext) +{ + for (String & e : plugin->exts) + { + if (!strcmp_nocase(e, ext)) + return true; + } + + return false; +} + +bool input_plugin_has_key(PluginHandle * plugin, InputKey key, + const char * value) +{ + for (String & s : plugin->keys[key]) + { + if (!strcmp_nocase(s, value)) + return true; + } + + return false; +} + +bool input_plugin_has_subtunes(PluginHandle * plugin) +{ + return plugin->has_subtunes; +} + +bool input_plugin_can_write_tuple(PluginHandle * plugin) +{ + return plugin->writes_tag; +} + +EXPORT Index<const char *> aud_plugin_get_supported_mime_types() +{ + Index<const char *> mimes; + + for (PluginHandle * p : aud_plugin_list(PluginType::Input)) + { + if (!aud_plugin_get_enabled(p)) + continue; + + for (auto & k : p->keys[InputKey::MIME]) + mimes.append((const char *)k); + } + + /* sort and remove duplicates */ + /* lambda needed to avoid -Wnoexcept-type with GCC */ + mimes.sort([](const char * a, const char * b) { return strcmp(a, b); }); + + int len = mimes.len(); + for (int i = 0; i + 1 < len; i++) + { + if (!strcmp(mimes[i], mimes[i + 1])) + mimes[i] = nullptr; + } + + mimes.remove_if([](const char * m) { return m == nullptr; }); + mimes.append(nullptr); + + return mimes; +} diff --git a/src/libaudcore/plugin.h b/src/libaudcore/plugin.h new file mode 100644 index 0000000..bd45fea --- /dev/null +++ b/src/libaudcore/plugin.h @@ -0,0 +1,543 @@ +/* + * plugin.h + * Copyright 2005-2013 Ariadne Conill, Yoshiki Yazawa, Eugene Zagidullin, and + * John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_PLUGIN_H +#define LIBAUDCORE_PLUGIN_H + +#include <libaudcore/audio.h> +#include <libaudcore/export.h> +#include <libaudcore/plugins.h> +#include <libaudcore/tuple.h> +#include <libaudcore/vfs.h> +#include <libaudcore/visualizer.h> + +enum class AudMenuID; +struct PluginPreferences; + +/* "Magic" bytes identifying an Audacious plugin header. */ +#define _AUD_PLUGIN_MAGIC ((int)0x8EAC8DE2) + +/* API version. Plugins are marked with this number at compile time. + * + * _AUD_PLUGIN_VERSION is the current version; _AUD_PLUGIN_VERSION_MIN is + * the oldest one we are backward compatible with. Plugins marked older than + * _AUD_PLUGIN_VERSION_MIN or newer than _AUD_PLUGIN_VERSION are not loaded. + * + * Before releases that add new pointers to the end of the API tables, increment + * _AUD_PLUGIN_VERSION but leave _AUD_PLUGIN_VERSION_MIN the same. + * + * Before releases that break backward compatibility (e.g. remove pointers from + * the API tables), increment _AUD_PLUGIN_VERSION *and* set + * _AUD_PLUGIN_VERSION_MIN to the same value. */ + +#define _AUD_PLUGIN_VERSION_MIN 48 /* 3.8-devel */ +#define _AUD_PLUGIN_VERSION 48 /* 3.8-devel */ + +/* Default priority. */ +#define _AUD_PLUGIN_DEFAULT_PRIO 5 + +/* A NOTE ON THREADS + * + * How thread-safe a plugin must be depends on the type of plugin. Note that + * some parts of the Audacious API are *not* thread-safe and therefore cannot be + * used in some parts of some plugins; for example, input plugins cannot use + * GUI-related calls or access the playlist except in about() and configure(). + * + * Thread-safe plugins: transport, playlist, input, effect, and output. These + * must be mostly thread-safe. init() and cleanup() may be called from + * secondary threads; however, no other functions provided by the plugin will be + * called at the same time. about() and configure() will be called only from + * the main thread. All other functions provided by the plugin may be called + * from any thread and from multiple threads simultaneously. + * + * Exceptions: + * - Because many existing input plugins are not coded to handle simultaneous + * calls to play(), play() will only be called from one thread at a time. New + * plugins should not rely on this exception, though. + * - Some combinations of calls, especially for output and effect plugins, make + * no sense; for example, flush() in an output plugin will only be called + * after open_audio() and before close_audio(). + * + * Single-thread plugins: visualization, general, and interface. Functions + * provided by these plugins will only be called from the main thread. */ + +/* CROSS-PLUGIN MESSAGES + * + * Since 3.2, Audacious implements a basic messaging system between plugins. + * Messages are sent using aud_plugin_send_message() and received through the + * take_message() method specified in the header of the receiving plugin. + * Plugins that do not need to receive messages can set take_message() to + * nullptr. + * + * Each message includes a code indicating the type of message, a pointer to + * some data, and a value indicating the size of that data. What the message + * data contains is entirely up to the two plugins involved. For this reason, it + * is crucial that both plugins agree on the meaning of the message codes used. + * + * Once the message is sent, an integer error code is returned. If the receiving + * plugin does not provide the take_message() method, -1 is returned. If + * take_message() does not recognize the message code, it should ignore the + * message and return -1. An error code of zero represents success. Other error + * codes may be used with more specific meanings. + * + * For the time being, aud_plugin_send_message() should only be called from the + * program's main thread. */ + +/* plugin flags */ +enum +{ + PluginGLibOnly = 0x1, // plugin requires GLib main loop + PluginQtOnly = 0x2 // plugin requires Qt main loop +}; + +struct PluginInfo +{ + const char * name; + const char * domain; // for gettext + const char * about; + const PluginPreferences * prefs; + int flags; +}; + +class LIBAUDCORE_PUBLIC Plugin +{ +public: + constexpr Plugin(PluginType type, PluginInfo info) : type(type), info(info) + { + } + + const int magic = _AUD_PLUGIN_MAGIC; + const int version = _AUD_PLUGIN_VERSION; + + const PluginType type; + const PluginInfo info; + + virtual bool init() { return true; } + virtual void cleanup() {} + + virtual int take_message(const char * code, const void * data, int size) + { + return -1; + } +}; + +class LIBAUDCORE_PUBLIC TransportPlugin : public Plugin +{ +public: + constexpr TransportPlugin(const PluginInfo info, + const ArrayRef<const char *> schemes) + : Plugin(PluginType::Transport, info), schemes(schemes) + { + } + + /* supported URI schemes (without "://") */ + const ArrayRef<const char *> schemes; + + virtual VFSImpl * fopen(const char * filename, const char * mode, + String & error) = 0; + + virtual VFSFileTest test_file(const char * filename, VFSFileTest test, + String & error) + { + return VFSFileTest(0); + } + + virtual Index<String> read_folder(const char * filename, String & error) + { + return Index<String>(); + } +}; + +class LIBAUDCORE_PUBLIC PlaylistPlugin : public Plugin +{ +public: + constexpr PlaylistPlugin(const PluginInfo info, + const ArrayRef<const char *> extensions, + bool can_save) + : Plugin(PluginType::Playlist, info), extensions(extensions), + can_save(can_save) + { + } + + /* supported file extensions (without periods) */ + const ArrayRef<const char *> extensions; + + /* true if the plugin can save playlists */ + const bool can_save; + + /* path: URI of playlist file (in) + * file: VFS handle of playlist file (in, read-only file, not seekable) + * title: title of playlist (out) + * items: playlist entries (out) */ + virtual bool load(const char * path, VFSFile & file, String & title, + Index<PlaylistAddItem> & items) = 0; + + /* path: URI of playlist file (in) + * file: VFS handle of playlist file (in, write-only file, not seekable) + * title: title of playlist (in) + * items: playlist entries (in) */ + virtual bool save(const char * path, VFSFile & file, const char * title, + const Index<PlaylistAddItem> & items) + { + return false; + } +}; + +class LIBAUDCORE_PUBLIC OutputPlugin : public Plugin +{ +public: + constexpr OutputPlugin(const PluginInfo info, int priority, + bool force_reopen = false) + : Plugin(PluginType::Output, info), priority(priority), + force_reopen(force_reopen) + { + } + + /* During probing, plugins with higher priority (10 to 0) are tried first. + */ + const int priority; + + /* Whether close_audio() and open_audio() must always be called between + * songs, even if the audio format is the same. Note that this defeats + * gapless playback. */ + const bool force_reopen; + + /* Returns current volume for left and right channels (0 to 100). */ + virtual StereoVolume get_volume() = 0; + + /* Changes volume for left and right channels (0 to 100). */ + virtual void set_volume(StereoVolume volume) = 0; + + /* Sets information about the song being played. This function will be + * called before open_audio(). */ + virtual void set_info(const char * filename, const Tuple & tuple) {} + + /* Begins playback of a PCM stream. <format> is one of the FMT_* + * enumeration values defined in libaudcore/audio.h. Returns true on + * success. */ + virtual bool open_audio(int format, int rate, int chans, + String & error) = 0; + + /* Ends playback. Any buffered audio data is discarded. */ + virtual void close_audio() = 0; + + /* Waits until write_audio() will return a size greater than zero. + * get_delay(), pause(), and flush() may be called meanwhile; if flush() + * is called, period_wait() should return immediately. */ + virtual void period_wait() = 0; + + /* Writes up to <size> bytes of data, in the format given to open_audio(). + * If there is not enough buffer space for all <size> bytes, writes only as + * many bytes as can be written immediately without blocking. Returns the + * number of bytes actually written. */ + virtual int write_audio(const void * data, int size) = 0; + + /* Waits until all buffered data has been heard by the user. */ + virtual void drain() = 0; + + /* Returns an estimate of how many milliseconds will pass before all the + * data passed to write_audio() has been heard by the user. */ + virtual int get_delay() = 0; + + /* Pauses the stream if <p> is nonzero; otherwise unpauses it. + * write_audio() will not be called while the stream is paused. */ + virtual void pause(bool pause) = 0; + + /* Discards any buffered audio data. */ + virtual void flush() = 0; +}; + +class LIBAUDCORE_PUBLIC EffectPlugin : public Plugin +{ +public: + constexpr EffectPlugin(const PluginInfo info, int order, + bool preserves_format) + : Plugin(PluginType::Effect, info), order(order), + preserves_format(preserves_format) + { + } + + /* Effects with lowest order (0 to 9) are applied first. */ + const int order; + + /* If the effect does not change the number of channels or the sampling + * rate, it can be enabled and disabled more smoothly. */ + const bool preserves_format; + + /* All processing is done in floating point. If the effect plugin wants to + * change the channel count or sample rate, it can change the parameters + * passed to start(). They cannot be changed in the middle of a song. */ + virtual void start(int & channels, int & rate) = 0; + + /* Performs effect processing. process() may modify the audio samples in + * place and return a reference to the same buffer, or it may return a + * reference to an internal working buffer. The number of output samples + * need not be the same as the number of input samples. */ + virtual Index<float> & process(Index<float> & data) = 0; + + /* Optional. A seek is taking place; any buffers should be discarded. + * Unless the "force" flag is set, the plugin may choose to override the + * normal flush behavior and handle the flush itself (for example, to + * perform crossfading). The flush() function should return false in this + * case to prevent flush() from being called in downstream effect plugins. + */ + virtual bool flush(bool force) { return true; } + + /* Exactly like process() except that any buffers should be drained (i.e. + * the data processed and returned). finish() will be called a second time + * at the end of the last song in the playlist. */ + virtual Index<float> & finish(Index<float> & data, bool end_of_playlist) + { + return process(data); + } + + /* Required only for plugins that change the time domain (e.g. a time + * stretch) or use read-ahead buffering. translate_delay() must do two + * things: first, translate <delay> (which is in milliseconds) from the + * output time domain back to the input time domain; second, increase + * <delay> by the size of the read-ahead buffer. It should return the + * adjusted delay. */ + virtual int adjust_delay(int delay) { return delay; } +}; + +enum class InputKey +{ + Ext, + MIME, + Scheme, + count +}; + +class LIBAUDCORE_PUBLIC InputPlugin : public Plugin +{ +public: + enum + { + /* Indicates that the plugin can write file tags */ + FlagWritesTag = (1 << 0), + + /* Indicates that files handled by the plugin may contain more than one + * song. When reading the tuple for such a file, the plugin should set + * the FIELD_SUBSONG_NUM field to the number of songs in the file. For + * all other files, the field should be left unset. + * + * Example: + * 1. User adds a file named "somefile.xxx" to the playlist. Having + * determined that this plugin can handle the file, Audacious opens the + * file and calls probe_for_tuple(). probe_for_tuple() sees that there + * are 3 songs in the file and sets FIELD_SUBSONG_NUM to 3. + * 2. For each song in the file, Audacious opens the file and calls + * probe_for_tuple(); this time, however, a question mark and song + * number are appended to the file name passed: "somefile.sid?2" refers + * to the second song in the file "somefile.sid". + * 3. When one of the songs is played, Audacious opens the file and + * calls play() with a file name modified in this way. */ + FlagSubtunes = (1 << 1) + }; + + struct InputInfo + { + typedef const char * const * List; + + int flags, priority; + aud::array<InputKey, List> keys; + + constexpr InputInfo(int flags = 0) + : flags(flags), priority(_AUD_PLUGIN_DEFAULT_PRIO), keys{} + { + } + + /* Associates file extensions with the plugin. */ + constexpr InputInfo with_exts(List exts) const + { + return InputInfo(flags, priority, exts, keys[InputKey::MIME], + keys[InputKey::Scheme]); + } + + /* Associates MIME types with the plugin. */ + constexpr InputInfo with_mimes(List mimes) const + { + return InputInfo(flags, priority, keys[InputKey::Ext], mimes, + keys[InputKey::Scheme]); + } + + /* Associates custom URI schemes with the plugin. Plugins using custom + * URI schemes are expected to handle their own I/O. Hence, any VFSFile + * passed to play(), read_tuple(), etc. will be null. */ + constexpr InputInfo with_schemes(List schemes) const + { + return InputInfo(flags, priority, keys[InputKey::Ext], + keys[InputKey::MIME], schemes); + } + + /* Sets how quickly the plugin should be tried in searching for a plugin + * to handle a file which could not be identified from its extension. + * Plugins with priority 0 are tried first, 10 last. */ + constexpr InputInfo with_priority(int priority) const + { + return InputInfo(flags, priority, keys[InputKey::Ext], + keys[InputKey::MIME], keys[InputKey::Scheme]); + } + + private: + constexpr InputInfo(int flags, int priority, List exts, List mimes, + List schemes) + : flags(flags), priority(priority), keys{exts, mimes, schemes} + { + } + }; + + constexpr InputPlugin(PluginInfo info, InputInfo input_info) + : Plugin(PluginType::Input, info), input_info(input_info) + { + } + + const InputInfo input_info; + + /* Returns true if the plugin can handle the file. */ + virtual bool is_our_file(const char * filename, VFSFile & file) = 0; + + /* Reads metadata and album art (if requested and available) from the file. + * The filename fields of the tuple are already set before the function is + * called. If album art is not needed, <image> will be nullptr. The return + * value should be true if <tuple> was successfully read, regardless of + * whether album art was read. */ + virtual bool read_tag(const char * filename, VFSFile & file, Tuple & tuple, + Index<char> * image) = 0; + + /* Plays the file. Returns false on error. Also see input-api.h. */ + virtual bool play(const char * filename, VFSFile & file) = 0; + + /* Optional. Writes metadata to the file, returning false on error. */ + virtual bool write_tuple(const char * filename, VFSFile & file, + const Tuple & tuple) + { + return false; + } + + /* Optional. Displays a window showing info about the file. In general, + * this function should be avoided since Audacious already provides a file + * info window. */ + virtual bool file_info_box(const char * filename, VFSFile & file) + { + return false; + } + +protected: + /* Prepares the output system for playback in the specified format. Also + * triggers the "playback ready" hook. Hence, if you call set_replay_gain, + * set_playback_tuple, or set_stream_bitrate, consider doing so before + * calling open_audio. There is no return value. If the requested audio + * format is not supported, write_audio() will do nothing and check_stop() + * will immediately return true. */ + static void open_audio(int format, int rate, int channels); + + /* Informs the output system of replay gain values for the current song so + * that volume levels can be adjusted accordingly, if the user so desires. + * This may be called at any time during playback should the values change. + */ + static void set_replay_gain(const ReplayGainInfo & gain); + + /* Passes audio data to the output system for playback. The data must be in + * the format passed to open_audio(), and the length (in bytes) must be an + * integral number of frames. This function blocks until all the data has + * been written (though it may not yet be heard by the user). */ + static void write_audio(const void * data, int length); + + /* Returns the current tuple for the stream. */ + static Tuple get_playback_tuple(); + + /* Updates the tuple for the stream. */ + static void set_playback_tuple(Tuple && tuple); + + /* Updates the displayed bitrate, in bits per second. */ + static void set_stream_bitrate(int bitrate); + + /* Checks whether playback is to be stopped. The play() function should + * poll check_stop() periodically and return as soon as check_stop() returns + * true. */ + static bool check_stop(); + + /* Checks whether a seek has been requested. If so, returns the position to + * seek to, in milliseconds. Otherwise, returns -1. */ + static int check_seek(); +}; + +class LIBAUDCORE_PUBLIC DockablePlugin : public Plugin +{ +public: + constexpr DockablePlugin(PluginType type, PluginInfo info) + : Plugin(type, info) + { + } + + /* GtkWidget * get_gtk_widget () */ + virtual void * get_gtk_widget() { return nullptr; } + + /* QWidget * get_qt_widget () */ + virtual void * get_qt_widget() { return nullptr; } +}; + +class LIBAUDCORE_PUBLIC GeneralPlugin : public DockablePlugin +{ +public: + constexpr GeneralPlugin(PluginInfo info, bool enabled_by_default) + : DockablePlugin(PluginType::General, info), + enabled_by_default(enabled_by_default) + { + } + + const bool enabled_by_default; +}; + +class LIBAUDCORE_PUBLIC VisPlugin : public DockablePlugin, public Visualizer +{ +public: + constexpr VisPlugin(PluginInfo info, int type_mask) + : DockablePlugin(PluginType::Vis, info), Visualizer(type_mask) + { + } +}; + +class LIBAUDCORE_PUBLIC IfacePlugin : public Plugin +{ +public: + constexpr IfacePlugin(PluginInfo info) : Plugin(PluginType::Iface, info) {} + + virtual void show(bool show) = 0; + virtual void run() = 0; + virtual void quit() = 0; + + virtual void show_about_window() = 0; + virtual void hide_about_window() = 0; + virtual void show_filebrowser(bool open) = 0; + virtual void hide_filebrowser() = 0; + virtual void show_jump_to_song() = 0; + virtual void hide_jump_to_song() = 0; + virtual void show_prefs_window() = 0; + virtual void hide_prefs_window() = 0; + virtual void plugin_menu_add(AudMenuID id, void func(), const char * name, + const char * icon) = 0; + virtual void plugin_menu_remove(AudMenuID id, void func()) = 0; + + virtual void startup_notify(const char * id) {} +}; + +#endif diff --git a/src/libaudcore/plugins-internal.h b/src/libaudcore/plugins-internal.h new file mode 100644 index 0000000..23ae67b --- /dev/null +++ b/src/libaudcore/plugins-internal.h @@ -0,0 +1,71 @@ +/* + * internal.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_PLUGINS_INTERNAL_H +#define LIBAUDCORE_PLUGINS_INTERNAL_H + +#include "objects.h" +#include "plugins.h" + +enum class InputKey; +class Plugin; + +enum class PluginEnabled +{ + Disabled = 0, + Primary = 1, + Secondary = 2 +}; + +/* plugin-init.c */ +void start_plugins_one(); +void start_plugins_two(); +void stop_plugins_two(); +void stop_plugins_one(); + +bool plugin_enable_secondary(PluginHandle * plugin, bool enable); + +/* plugin-load.c */ +void plugin_system_init(); +void plugin_system_cleanup(); +bool plugin_check_flags(int flags); +Plugin * plugin_load(const char * path); + +/* plugin-registry.c */ +void plugin_registry_load(); +void plugin_registry_prune(); +void plugin_registry_save(); +void plugin_registry_cleanup(); + +void plugin_register(const char * path, int timestamp); +PluginEnabled plugin_get_enabled(PluginHandle * plugin); +void plugin_set_enabled(PluginHandle * plugin, PluginEnabled enabled); +void plugin_set_failed(PluginHandle * plugin); + +const Index<String> & transport_plugin_get_schemes(PluginHandle * plugin); +bool transport_plugin_has_scheme(PluginHandle * plugin, const char * scheme); +bool playlist_plugin_can_save(PluginHandle * plugin); +const Index<String> & playlist_plugin_get_exts(PluginHandle * plugin); +bool playlist_plugin_has_ext(PluginHandle * plugin, const char * ext); +bool input_plugin_has_key(PluginHandle * plugin, InputKey key, + const char * value); +bool input_plugin_has_subtunes(PluginHandle * plugin); +bool input_plugin_can_write_tuple(PluginHandle * plugin); + +#endif diff --git a/src/libaudcore/plugins.h b/src/libaudcore/plugins.h new file mode 100644 index 0000000..bf156f6 --- /dev/null +++ b/src/libaudcore/plugins.h @@ -0,0 +1,75 @@ +/* + * plugins.h + * Copyright 2010-2012 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_PLUGINS_H +#define LIBAUDCORE_PLUGINS_H + +#include <libaudcore/index.h> + +enum class PluginType +{ + Transport, + Playlist, + Input, + Effect, + Output, + Vis, + General, + Iface, + count +}; + +class PluginHandle; + +/* CAUTION: These functions are not thread safe. */ + +PluginHandle * aud_plugin_get_current(PluginType type); +bool aud_plugin_get_enabled(PluginHandle * plugin); +bool aud_plugin_enable(PluginHandle * plugin, bool enable); + +int aud_plugin_send_message(PluginHandle * plugin, const char * code, + const void * data, int size); +void * +aud_plugin_get_gtk_widget(PluginHandle * plugin); // returns (GtkWidget *) +void * aud_plugin_get_qt_widget(PluginHandle * plugin); // return (QWidget *) + +PluginType aud_plugin_get_type(PluginHandle * plugin); +const char * aud_plugin_get_basename(PluginHandle * plugin); +PluginHandle * aud_plugin_lookup_basename(const char * basename); + +const void * aud_plugin_get_header(PluginHandle * plugin); +PluginHandle * aud_plugin_by_header(const void * header); + +const Index<PluginHandle *> & aud_plugin_list(PluginType type); + +const char * aud_plugin_get_name(PluginHandle * plugin); +bool aud_plugin_has_about(PluginHandle * plugin); +bool aud_plugin_has_configure(PluginHandle * plugin); + +/* returns true to continue watching, false to stop */ +typedef bool (*PluginWatchFunc)(PluginHandle * plugin, void * data); + +void aud_plugin_add_watch(PluginHandle * plugin, PluginWatchFunc func, + void * data); +void aud_plugin_remove_watch(PluginHandle * plugin, PluginWatchFunc func, + void * data); + +Index<const char *> aud_plugin_get_supported_mime_types(); + +#endif diff --git a/src/libaudcore/preferences.cc b/src/libaudcore/preferences.cc new file mode 100644 index 0000000..3d6d8a2 --- /dev/null +++ b/src/libaudcore/preferences.cc @@ -0,0 +1,123 @@ +/* + * preferences.cc + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "preferences.h" +#include "runtime.h" + +#include <assert.h> + +EXPORT bool WidgetConfig::get_bool() const +{ + assert(type == Bool); + + if (value) + return *(bool *)value; + else if (name) + return aud_get_bool(section, name); + else + return false; +} + +EXPORT void WidgetConfig::set_bool(bool val) const +{ + assert(type == Bool); + + if (value) + *(bool *)value = val; + else if (name) + aud_set_bool(section, name, val); + + if (callback) + callback(); +} + +EXPORT int WidgetConfig::get_int() const +{ + assert(type == Int); + + if (value) + return *(int *)value; + else if (name) + return aud_get_int(section, name); + else + return 0; +} + +EXPORT void WidgetConfig::set_int(int val) const +{ + assert(type == Int); + + if (value) + *(int *)value = val; + else if (name) + aud_set_int(section, name, val); + + if (callback) + callback(); +} + +EXPORT double WidgetConfig::get_float() const +{ + assert(type == Float); + + if (value) + return *(double *)value; + else if (name) + return aud_get_double(section, name); + else + return 0; +} + +EXPORT void WidgetConfig::set_float(double val) const +{ + assert(type == Float); + + if (value) + *(double *)value = val; + else if (name) + aud_set_double(section, name, val); + + if (callback) + callback(); +} + +EXPORT String WidgetConfig::get_string() const +{ + assert(type == String); + + if (value) + return *(::String *)value; + else if (name) + return aud_get_str(section, name); + else + return ::String(); +} + +EXPORT void WidgetConfig::set_string(const char * val) const +{ + assert(type == String); + + if (value) + *(::String *)value = ::String(val); + else if (name) + aud_set_str(section, name, val); + + if (callback) + callback(); +} diff --git a/src/libaudcore/preferences.h b/src/libaudcore/preferences.h new file mode 100644 index 0000000..957c928 --- /dev/null +++ b/src/libaudcore/preferences.h @@ -0,0 +1,409 @@ +/* + * preferences.h + * Copyright 2007-2014 Tomasz Moń, Ariadne Conill, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_PREFERENCES_H +#define LIBAUDCORE_PREFERENCES_H + +#include <libaudcore/objects.h> + +struct PreferencesWidget; + +enum class FileSelectMode +{ + File, + Folder +}; + +struct ComboItem +{ + const char * label; + const char * str; + int num; + + constexpr ComboItem(const char * label, const char * str) + : label(label), str(str), num(-1) + { + } + + constexpr ComboItem(const char * label, int num) + : label(label), str(nullptr), num(num) + { + } +}; + +struct WidgetVButton +{ + void (*callback)(); + const char * icon; +}; + +struct WidgetVRadio +{ + int value; +}; + +struct WidgetVSpin +{ + double min, max, step; + const char * right_label; /* text right to widget */ +}; + +struct WidgetVTable +{ + ArrayRef<PreferencesWidget> widgets; +}; + +struct WidgetVFonts +{ + const char * title; +}; + +struct WidgetVEntry +{ + bool password; +}; + +struct WidgetVFileEntry +{ + FileSelectMode mode; +}; + +struct WidgetVCombo +{ + /* static init */ + ArrayRef<ComboItem> elems; + + /* runtime init */ + ArrayRef<ComboItem> (*fill)(); +}; + +struct WidgetVBox +{ + ArrayRef<PreferencesWidget> widgets; + + bool horizontal; /* false gives vertical, true gives horizontal alignment of + child widgets */ + bool frame; /* whether to draw frame around box */ +}; + +struct NotebookTab +{ + const char * name; + ArrayRef<PreferencesWidget> widgets; +}; + +struct WidgetVNotebook +{ + ArrayRef<NotebookTab> tabs; +}; + +struct WidgetVSeparator +{ + bool horizontal; /* false gives vertical, true gives horizontal separator */ +}; + +union WidgetVariant { + WidgetVButton button; + WidgetVRadio radio_btn; + WidgetVSpin spin_btn; + WidgetVTable table; + WidgetVFonts font_btn; + WidgetVEntry entry; + WidgetVFileEntry file_entry; + WidgetVCombo combo; + WidgetVBox box; + WidgetVNotebook notebook; + WidgetVSeparator separator; + + /* for custom GTK or Qt widgets */ + /* GtkWidget * (* populate) (); */ + /* QWidget * (* populate) (); */ + void * (*populate)(); + + constexpr WidgetVariant(WidgetVButton button) : button(button) {} + constexpr WidgetVariant(WidgetVRadio radio) : radio_btn(radio) {} + constexpr WidgetVariant(WidgetVSpin spin) : spin_btn(spin) {} + constexpr WidgetVariant(WidgetVTable table) : table(table) {} + constexpr WidgetVariant(WidgetVFonts fonts) : font_btn(fonts) {} + constexpr WidgetVariant(WidgetVEntry entry) : entry(entry) {} + constexpr WidgetVariant(WidgetVFileEntry file_entry) + : file_entry(file_entry) + { + } + constexpr WidgetVariant(WidgetVCombo combo) : combo(combo) {} + constexpr WidgetVariant(WidgetVBox box) : box(box) {} + constexpr WidgetVariant(WidgetVNotebook notebook) : notebook(notebook) {} + constexpr WidgetVariant(WidgetVSeparator separator) : separator(separator) + { + } + + /* also serves as default constructor */ + constexpr WidgetVariant(void * (*populate)() = 0) : populate(populate) {} +}; + +struct WidgetConfig +{ + enum Type + { + None, + Bool, + Int, + Float, + String + }; + + Type type; + + /* pointer to immediate value */ + void * value; + /* identifier for configuration value */ + const char *section, *name; + /* called when value is changed */ + void (*callback)(); + /* widget updates when this hook is called */ + const char * hook; + + constexpr WidgetConfig() + : type(None), value(nullptr), section(nullptr), name(nullptr), + callback(nullptr), hook(nullptr) + { + } + + constexpr WidgetConfig(Type type, void * value, const char * section, + const char * name, void (*callback)(), + const char * hook) + : type(type), value(value), section(section), name(name), + callback(callback), hook(hook) + { + } + + bool get_bool() const; + void set_bool(bool val) const; + int get_int() const; + void set_int(int val) const; + double get_float() const; + void set_float(double val) const; + ::String get_string() const; + void set_string(const char * val) const; +}; + +constexpr WidgetConfig WidgetBool(bool & value, void (*callback)() = nullptr, + const char * hook = nullptr) +{ + return WidgetConfig(WidgetConfig::Bool, (void *)&value, 0, 0, callback, + hook); +} +constexpr WidgetConfig WidgetInt(int & value, void (*callback)() = nullptr, + const char * hook = nullptr) +{ + return WidgetConfig(WidgetConfig::Int, (void *)&value, 0, 0, callback, + hook); +} +constexpr WidgetConfig WidgetFloat(double & value, void (*callback)() = nullptr, + const char * hook = nullptr) +{ + return WidgetConfig(WidgetConfig::Float, (void *)&value, 0, 0, callback, + hook); +} +constexpr WidgetConfig WidgetString(String & value, + void (*callback)() = nullptr, + const char * hook = nullptr) +{ + return WidgetConfig(WidgetConfig::String, (void *)&value, 0, 0, callback, + hook); +} + +constexpr WidgetConfig WidgetBool(const char * section, const char * name, + void (*callback)() = nullptr, + const char * hook = nullptr) +{ + return WidgetConfig(WidgetConfig::Bool, 0, section, name, callback, hook); +} +constexpr WidgetConfig WidgetInt(const char * section, const char * name, + void (*callback)() = nullptr, + const char * hook = nullptr) +{ + return WidgetConfig(WidgetConfig::Int, 0, section, name, callback, hook); +} +constexpr WidgetConfig WidgetFloat(const char * section, const char * name, + void (*callback)() = nullptr, + const char * hook = nullptr) +{ + return WidgetConfig(WidgetConfig::Float, 0, section, name, callback, hook); +} +constexpr WidgetConfig WidgetString(const char * section, const char * name, + void (*callback)() = nullptr, + const char * hook = nullptr) +{ + return WidgetConfig(WidgetConfig::String, 0, section, name, callback, hook); +} + +struct PreferencesWidget +{ + enum Type + { + Label, + Button, + CheckButton, + RadioButton, + SpinButton, + Entry, + FileEntry, + ComboBox, + FontButton, + Box, + Table, + Notebook, + Separator, + CustomGTK, + CustomQt + }; + + Type type; + const char * + label; /* widget title (for SPIN_BTN it's text left to widget) */ + bool child; + + WidgetConfig cfg; + WidgetVariant data; +}; + +enum WidgetIsChild +{ + WIDGET_NOT_CHILD, + WIDGET_CHILD +}; + +constexpr PreferencesWidget WidgetLabel(const char * label, + WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return {PreferencesWidget::Label, label, (child == WIDGET_CHILD)}; +} + +constexpr PreferencesWidget WidgetButton(const char * label, + WidgetVButton button, + WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return { + PreferencesWidget::Button, label, (child == WIDGET_CHILD), {}, button}; +} + +constexpr PreferencesWidget WidgetCheck(const char * label, WidgetConfig cfg, + WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return {PreferencesWidget::CheckButton, label, (child == WIDGET_CHILD), + cfg}; +} + +constexpr PreferencesWidget WidgetRadio(const char * label, WidgetConfig cfg, + WidgetVRadio radio, + WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return {PreferencesWidget::RadioButton, label, (child == WIDGET_CHILD), cfg, + radio}; +} + +constexpr PreferencesWidget WidgetSpin(const char * label, WidgetConfig cfg, + WidgetVSpin spin, + WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return {PreferencesWidget::SpinButton, label, (child == WIDGET_CHILD), cfg, + spin}; +} + +constexpr PreferencesWidget WidgetEntry(const char * label, WidgetConfig cfg, + WidgetVEntry entry = WidgetVEntry(), + WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return {PreferencesWidget::Entry, label, (child == WIDGET_CHILD), cfg, + entry}; +} + +constexpr PreferencesWidget +WidgetFileEntry(const char * label, WidgetConfig cfg, + WidgetVFileEntry file_entry = WidgetVFileEntry(), + WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return {PreferencesWidget::FileEntry, label, (child == WIDGET_CHILD), cfg, + file_entry}; +} + +constexpr PreferencesWidget WidgetCombo(const char * label, WidgetConfig cfg, + WidgetVCombo combo, + WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return {PreferencesWidget::ComboBox, label, (child == WIDGET_CHILD), cfg, + combo}; +} + +constexpr PreferencesWidget WidgetFonts(const char * label, WidgetConfig cfg, + WidgetVFonts fonts, + WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return {PreferencesWidget::FontButton, label, (child == WIDGET_CHILD), cfg, + fonts}; +} + +constexpr PreferencesWidget WidgetBox(WidgetVBox box, + WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return {PreferencesWidget::Box, 0, (child == WIDGET_CHILD), {}, box}; +} + +constexpr PreferencesWidget WidgetTable(WidgetVTable table, + WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return {PreferencesWidget::Table, 0, (child == WIDGET_CHILD), {}, table}; +} + +constexpr PreferencesWidget WidgetNotebook(WidgetVNotebook notebook) +{ + return {PreferencesWidget::Notebook, 0, 0, {}, notebook}; +} + +constexpr PreferencesWidget +WidgetSeparator(WidgetVSeparator separator = WidgetVSeparator()) +{ + return {PreferencesWidget::Separator, 0, 0, {}, separator}; +} + +constexpr PreferencesWidget +WidgetCustomGTK(void * (*populate)(), WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return { + PreferencesWidget::CustomGTK, 0, (child == WIDGET_CHILD), {}, populate}; +} + +constexpr PreferencesWidget +WidgetCustomQt(void * (*populate)(), WidgetIsChild child = WIDGET_NOT_CHILD) +{ + return { + PreferencesWidget::CustomQt, 0, (child == WIDGET_CHILD), {}, populate}; +} + +struct PluginPreferences +{ + ArrayRef<PreferencesWidget> widgets; + + void (*init)(); + void (*apply)(); + void (*cleanup)(); +}; + +#endif /* LIBAUDCORE_PREFERENCES_H */ diff --git a/src/libaudcore/probe-buffer.cc b/src/libaudcore/probe-buffer.cc new file mode 100644 index 0000000..f5ce248 --- /dev/null +++ b/src/libaudcore/probe-buffer.cc @@ -0,0 +1,167 @@ +/* + * probe-buffer.c + * Copyright 2010-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "probe-buffer.h" +#include "runtime.h" + +#include <string.h> + +static constexpr int MAXBUF = 256 * 1024; + +ProbeBuffer::ProbeBuffer(const char * filename, VFSImpl * file) + : m_filename(filename), m_file(file) +{ + AUDINFO("<%p> buffering enabled for %s\n", this, (const char *)m_filename); +} + +ProbeBuffer::~ProbeBuffer() { delete[] m_buffer; } + +void ProbeBuffer::increase_buffer(int64_t size) +{ + size = aud::min((size + 0xFF) & ~0xFF, (int64_t)MAXBUF); + + if (m_filled < size) + { + if (!m_buffer) + m_buffer = new char[MAXBUF]; + + m_filled += m_file->fread(m_buffer + m_filled, 1, size - m_filled); + } +} + +void ProbeBuffer::release_buffer() +{ + AUDINFO("<%p> buffering disabled for %s\n", this, (const char *)m_filename); + delete[] m_buffer; + m_buffer = nullptr; + m_filled = 0; + m_at = -1; +} + +int64_t ProbeBuffer::fread(void * buffer, int64_t size, int64_t count) +{ + int64_t total = 0; + int64_t remain = size * count; + + /* read from buffer if possible */ + if (remain && m_at >= 0 && m_at < MAXBUF) + { + increase_buffer(m_at + remain); + + int copy = aud::min(remain, (int64_t)(m_filled - m_at)); + memcpy(buffer, m_buffer + m_at, copy); + + m_at += copy; + buffer = (char *)buffer + copy; + total += copy; + remain -= copy; + } + + /* then read from real file if allowed */ + if (remain && !m_limited) + { + /* release buffer if leaving bufferable area */ + if (m_at == MAXBUF) + release_buffer(); + + if (m_at < 0) + total += m_file->fread(buffer, 1, remain); + } + + return (size > 0) ? total / size : 0; +} + +int64_t ProbeBuffer::fwrite(const void * data, int64_t size, int64_t count) +{ + return 0; /* not allowed */ +} + +int ProbeBuffer::fseek(int64_t offset, VFSSeekType whence) +{ + /* seek within the buffer if possible */ + if (m_at >= 0 && whence != VFS_SEEK_END) + { + /* calculate requested position */ + if (whence == VFS_SEEK_CUR) + { + offset += m_at; + whence = VFS_SEEK_SET; + } + + if (offset < 0) + return -1; /* invalid argument */ + + if (offset <= MAXBUF) + { + increase_buffer(offset); + + if (offset > m_filled) + return -1; /* seek past end of file */ + + m_at = offset; + return 0; + } + } + + /* seek within real file if allowed */ + if (m_limited || m_file->fseek(offset, whence) < 0) + return -1; + + /* release buffer only if real seek succeeded + * (prevents change of file position if seek failed) */ + if (m_at >= 0) + release_buffer(); + + /* activate buffering again when seeking to beginning of file */ + if (whence == VFS_SEEK_SET && offset == 0) + { + AUDINFO("<%p> buffering enabled for %s\n", this, + (const char *)m_filename); + m_at = 0; + } + + return 0; +} + +int64_t ProbeBuffer::ftell() +{ + if (m_at >= 0) + return m_at; + + return m_file->ftell(); +} + +bool ProbeBuffer::feof() +{ + if (m_at >= 0 && m_at < m_filled) + return false; + + return m_file->feof(); +} + +int ProbeBuffer::ftruncate(int64_t size) { return -1; /* not allowed */ } + +int ProbeBuffer::fflush() { return 0; /* no-op */ } + +int64_t ProbeBuffer::fsize() { return m_file->fsize(); } + +String ProbeBuffer::get_metadata(const char * field) +{ + return m_file->get_metadata(field); +} diff --git a/src/libaudcore/probe-buffer.h b/src/libaudcore/probe-buffer.h new file mode 100644 index 0000000..1f85b69 --- /dev/null +++ b/src/libaudcore/probe-buffer.h @@ -0,0 +1,71 @@ +/* + * probe-buffer.h + * Copyright 2015 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_PROBE_BUFFER_H +#define LIBAUDCORE_PROBE_BUFFER_H + +/* The buffer is only for the beginning of the file, to allow detecting the file + * type without reading from the file repeatedly. Whenever buffering is active, + * m_at indicates the virtual file position, while the real file position is at + * the end of the buffer. Once it is necessary to read outside the buffer, m_at + * is set to -1, the buffer memory is released, and all file operations are done + * on the real file. Seeking to the beginning of the file activates buffering + * again. + * + * Optionally, reads can be restricted to the bufferable area. In this case, + * reads will stop short at the end of the bufferable area, and seeks outside + * the bufferable area (and any type of SEEK_END) will fail. However, the real + * file size is still reported. + */ + +#include "vfs.h" + +class ProbeBuffer : public VFSImpl +{ +public: + ProbeBuffer(const char * filename, VFSImpl * file); + ~ProbeBuffer(); + + int64_t fread(void * ptr, int64_t size, int64_t nmemb); + int fseek(int64_t offset, VFSSeekType whence); + + int64_t ftell(); + int64_t fsize(); + bool feof(); + + int64_t fwrite(const void * ptr, int64_t size, int64_t nmemb); + int ftruncate(int64_t length); + int fflush(); + + String get_metadata(const char * field); + + void set_limit_to_buffer(bool limit) { m_limited = limit; } + +private: + void increase_buffer(int64_t size); + void release_buffer(); + + String m_filename; + SmartPtr<VFSImpl> m_file; + char * m_buffer = nullptr; + int m_filled = 0, m_at = 0; + bool m_limited = false; +}; + +#endif // LIBAUDCORE_PROBE_BUFFER_H diff --git a/src/libaudcore/probe.cc b/src/libaudcore/probe.cc new file mode 100644 index 0000000..5868167 --- /dev/null +++ b/src/libaudcore/probe.cc @@ -0,0 +1,267 @@ +/* + * probe.c + * Copyright 2009-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "probe.h" +#include "internal.h" + +#include <string.h> + +#include "audstrings.h" +#include "i18n.h" +#include "playlist.h" +#include "plugin.h" +#include "plugins-internal.h" +#include "runtime.h" + +bool open_input_file(const char * filename, const char * mode, InputPlugin * ip, + VFSFile & file, String * error) +{ + /* no need to open a handle for custom URI schemes */ + if (ip && ip->input_info.keys[InputKey::Scheme]) + return true; + + /* already open? */ + if (file && file.fseek(0, VFS_SEEK_SET) == 0) + return true; + + file = VFSFile(filename, mode); + if (!file && error) + *error = String(file.error()); + + return (bool)file; +} + +InputPlugin * load_input_plugin(PluginHandle * decoder, String * error) +{ + auto ip = (InputPlugin *)aud_plugin_get_header(decoder); + if (!ip && error) + *error = String(_("Error loading plugin")); + + return ip; +} + +/* figure out some basic info without opening the file */ +int probe_by_filename(const char * filename) +{ + int flags = 0; + auto & list = aud_plugin_list(PluginType::Input); + + StringBuf scheme = uri_get_scheme(filename); + StringBuf ext = uri_get_extension(filename); + + for (PluginHandle * plugin : list) + { + if (!aud_plugin_get_enabled(plugin)) + continue; + + if ((scheme && + input_plugin_has_key(plugin, InputKey::Scheme, scheme)) || + (ext && input_plugin_has_key(plugin, InputKey::Ext, ext))) + { + flags |= PROBE_FLAG_HAS_DECODER; + if (input_plugin_has_subtunes(plugin)) + flags |= PROBE_FLAG_MIGHT_HAVE_SUBTUNES; + } + } + + return flags; +} + +EXPORT PluginHandle * aud_file_find_decoder(const char * filename, bool fast, + VFSFile & file, String * error) +{ + AUDINFO("%s %s.\n", fast ? "Fast-probing" : "Probing", filename); + + auto & list = aud_plugin_list(PluginType::Input); + + StringBuf scheme = uri_get_scheme(filename); + StringBuf ext = uri_get_extension(filename); + Index<PluginHandle *> ext_matches; + + for (PluginHandle * plugin : list) + { + if (!aud_plugin_get_enabled(plugin)) + continue; + + if (scheme && input_plugin_has_key(plugin, InputKey::Scheme, scheme)) + { + AUDINFO("Matched %s by URI scheme.\n", aud_plugin_get_name(plugin)); + return plugin; + } + + if (ext && input_plugin_has_key(plugin, InputKey::Ext, ext)) + ext_matches.append(plugin); + } + + if (ext_matches.len() == 1) + { + AUDINFO("Matched %s by extension.\n", + aud_plugin_get_name(ext_matches[0])); + return ext_matches[0]; + } + + AUDDBG("Matched %d plugins by extension.\n", ext_matches.len()); + + if (fast && !ext_matches.len()) + return nullptr; + + AUDDBG("Opening %s.\n", filename); + + if (!open_input_file(filename, "r", nullptr, file, error)) + { + AUDINFO("Open failed.\n"); + return nullptr; + } + + String mime = file.get_metadata("content-type"); + + if (mime) + { + for (PluginHandle * plugin : (ext_matches.len() ? ext_matches : list)) + { + if (!aud_plugin_get_enabled(plugin)) + continue; + + if (input_plugin_has_key(plugin, InputKey::MIME, mime)) + { + AUDINFO("Matched %s by MIME type %s.\n", + aud_plugin_get_name(plugin), (const char *)mime); + return plugin; + } + } + } + + file.set_limit_to_buffer(true); + + for (PluginHandle * plugin : (ext_matches.len() ? ext_matches : list)) + { + if (!aud_plugin_get_enabled(plugin)) + continue; + + AUDINFO("Trying %s.\n", aud_plugin_get_name(plugin)); + + auto ip = (InputPlugin *)aud_plugin_get_header(plugin); + if (!ip) + continue; + + if (ip->is_our_file(filename, file)) + { + AUDINFO("Matched %s by content.\n", aud_plugin_get_name(plugin)); + file.set_limit_to_buffer(false); + return plugin; + } + + if (file.fseek(0, VFS_SEEK_SET) != 0) + { + if (error) + *error = String(_("Seek error")); + + AUDINFO("Seek failed.\n"); + return nullptr; + } + } + + if (error) + *error = String(_("File format not recognized")); + + AUDINFO("No plugins matched.\n"); + return nullptr; +} + +EXPORT bool aud_file_read_tag(const char * filename, PluginHandle * decoder, + VFSFile & file, Tuple & tuple, + Index<char> * image, String * error) +{ + auto ip = load_input_plugin(decoder, error); + if (!ip) + return false; + + if (!open_input_file(filename, "r", ip, file, error)) + return false; + + Tuple new_tuple; + new_tuple.set_filename(filename); + + if (ip->read_tag(filename, file, new_tuple, image)) + { + // cleanly replace existing tuple + new_tuple.set_state(Tuple::Valid); + tuple = std::move(new_tuple); + return true; + } + + if (error) + *error = String(_("Error reading metadata")); + + return false; +} + +EXPORT bool aud_file_can_write_tuple(const char * filename, + PluginHandle * decoder) +{ + return input_plugin_can_write_tuple(decoder); +} + +EXPORT bool aud_file_write_tuple(const char * filename, PluginHandle * decoder, + const Tuple & tuple) +{ + auto ip = (InputPlugin *)aud_plugin_get_header(decoder); + if (!ip) + return false; + + VFSFile file; + if (!open_input_file(filename, "r+", ip, file)) + return false; + + bool success = ip->write_tuple(filename, file, tuple); + + if (success && file && file.fflush() != 0) + success = false; + + if (success) + Playlist::rescan_file(filename); + + return success; +} + +EXPORT bool aud_custom_infowin(const char * filename, PluginHandle * decoder) +{ + // blacklist stdin + if (!strncmp(filename, "stdin://", 8)) + return false; + + // In hindsight, a flag should have been added indicating whether a + // plugin provides a custom info window or not. Currently, only two + // plugins do so. Since custom info windows are deprecated anyway, + // check for those two plugins explicitly and in all other cases, + // don't open the input file to prevent freezing the UI. + const char * base = aud_plugin_get_basename(decoder); + if (strcmp(base, "amidi-plug") && strcmp(base, "vtx")) + return false; + + auto ip = (InputPlugin *)aud_plugin_get_header(decoder); + if (!ip) + return false; + + VFSFile file; + if (!open_input_file(filename, "r", ip, file)) + return false; + + return ip->file_info_box(filename, file); +} diff --git a/src/libaudcore/probe.h b/src/libaudcore/probe.h new file mode 100644 index 0000000..c2be567 --- /dev/null +++ b/src/libaudcore/probe.h @@ -0,0 +1,97 @@ +/* + * probe.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_PROBE_H +#define LIBAUDCORE_PROBE_H + +#include <libaudcore/index.h> +#include <libaudcore/objects.h> + +class PluginHandle; +class Tuple; +class VFSFile; + +/* ====== ALBUM ART API ====== */ + +/* request format */ +enum +{ + AUD_ART_DATA = (1 << 0), /* image data in memory */ + AUD_ART_FILE = (1 << 1) /* filename of image data on disk */ +}; + +/* opaque type storing art data */ +struct AudArtItem; + +/* don't use these directly, use AudArtPtr */ +const Index<char> * aud_art_data(const AudArtItem * item); +const char * aud_art_file(const AudArtItem * item); +void aud_art_unref(AudArtItem * item); + +/* handle for accessing/tracking album art data */ +class AudArtPtr : public SmartPtr<AudArtItem, aud_art_unref> +{ +public: + AudArtPtr() : SmartPtr() {} + explicit AudArtPtr(AudArtItem * ptr) : SmartPtr(ptr) {} + + const Index<char> * data() const + { + return get() ? aud_art_data(get()) : nullptr; + } + const char * file() const { return get() ? aud_art_file(get()) : nullptr; } +}; + +/* + * Gets album art for <file> (the URI of a song file). The data will be + * returned in the requested <format> (AUD_ART_DATA or AUD_ART_FILE). + * + * This is a non-blocking call. If the data is not yet loaded, it sets *queued + * to true, returns a null pointer, and begins to load the data in the back- + * ground. On completion, the "art ready" hook is called, with <file> as a + * parameter. The data can then be requested again from within the hook. + * + * As a special case, album art data for the currently playing song is preloaded + * by the time the "playback ready" hook is called, so in that case there is no + * need to implement a separate "art ready" handler. + * + * On error, a null pointer is returned and *queued is set to false. + */ +AudArtPtr aud_art_request(const char * file, int format, + bool * queued = nullptr); + +/* ====== GENERAL PROBING API ====== */ + +/* The following two functions take an additional VFSFile parameter to allow + * opening a file, probing for a decoder, and then reading the song metadata + * without opening the file a second time. If you don't already have a file + * handle open, then just pass in a null VFSFile and it will be opened for you. + */ +PluginHandle * aud_file_find_decoder(const char * filename, bool fast, + VFSFile & file, String * error = nullptr); +bool aud_file_read_tag(const char * filename, PluginHandle * decoder, + VFSFile & file, Tuple & tuple, + Index<char> * image = nullptr, String * error = nullptr); + +bool aud_file_can_write_tuple(const char * filename, PluginHandle * decoder); +bool aud_file_write_tuple(const char * filename, PluginHandle * decoder, + const Tuple & tuple); +bool aud_custom_infowin(const char * filename, PluginHandle * decoder); + +#endif diff --git a/src/libaudcore/ringbuf.cc b/src/libaudcore/ringbuf.cc new file mode 100644 index 0000000..0c5fef1 --- /dev/null +++ b/src/libaudcore/ringbuf.cc @@ -0,0 +1,198 @@ +/* + * ringbuf.cc + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "ringbuf.h" +#include "internal.h" + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +void RingBufBase::get_areas(int pos, int len, Areas & areas) +{ + assert(pos >= 0 && len >= 0 && pos + len <= m_len); + + int start = (m_offset + pos) % m_size; + int part = aud::min(len, m_size - start); + + areas.area1 = (char *)m_data + start; + areas.area2 = m_data; + areas.len1 = part; + areas.len2 = len - part; +} + +void RingBufBase::do_realloc(int size) +{ + void * mem = realloc(m_data, size); + if (size && !mem) + throw std::bad_alloc(); /* nothing changed yet */ + + m_data = mem; +} + +EXPORT void RingBufBase::alloc(int size) +{ + assert(size >= m_len); + + if (size == m_size) + return; + + /* reallocate first when growing */ + if (size > m_size) + do_realloc(size); + + __sync_add_and_fetch(&misc_bytes_allocated, size - m_size); + + int old_size = m_size; + int to_end = m_size - m_offset; + + m_size = size; + + if (to_end < m_len) + { + int new_offset = size - to_end; + memmove((char *)m_data + new_offset, (char *)m_data + m_offset, to_end); + m_offset = new_offset; + } + + /* reallocate last when shrinking */ + if (size < old_size) + do_realloc(size); +} + +EXPORT void RingBufBase::destroy(aud::EraseFunc erase_func) +{ + if (!m_data) + return; + + __sync_sub_and_fetch(&misc_bytes_allocated, m_size); + + discard(-1, erase_func); + + free(m_data); + m_data = nullptr; + m_size = 0; +} + +EXPORT void RingBufBase::add(int len) +{ + assert(len >= 0 && m_len + len <= m_size); + m_len += len; +} + +EXPORT void RingBufBase::remove(int len) +{ + assert(len >= 0 && len <= m_len); + + if (len == m_len) + m_offset = m_len = 0; + else + { + m_offset = (m_offset + len) % m_size; + m_len -= len; + } +} + +EXPORT void RingBufBase::copy_in(const void * from, int len, + aud::CopyFunc copy_func) +{ + Areas areas; + add(len); + get_areas(m_len - len, len, areas); + + if (copy_func) + { + copy_func(from, areas.area1, areas.len1); + copy_func((const char *)from + areas.len1, areas.area2, areas.len2); + } + else + { + memcpy(areas.area1, from, areas.len1); + memcpy(areas.area2, (const char *)from + areas.len1, areas.len2); + } +} + +EXPORT void RingBufBase::move_in(void * from, int len, aud::FillFunc fill_func) +{ + Areas areas; + add(len); + get_areas(m_len - len, len, areas); + + memcpy(areas.area1, from, areas.len1); + memcpy(areas.area2, (const char *)from + areas.len1, areas.len2); + + if (fill_func) + fill_func(from, len); +} + +EXPORT void RingBufBase::move_out(void * to, int len, aud::EraseFunc erase_func) +{ + Areas areas; + get_areas(0, len, areas); + + if (erase_func) + erase_func(to, len); + + memcpy(to, areas.area1, areas.len1); + memcpy((char *)to + areas.len1, areas.area2, areas.len2); + + remove(len); +} + +EXPORT void RingBufBase::discard(int len, aud::EraseFunc erase_func) +{ + if (!m_data) + return; + + if (len < 0) + len = m_len; + + if (erase_func) + { + Areas areas; + get_areas(0, len, areas); + erase_func(areas.area1, areas.len1); + erase_func(areas.area2, areas.len2); + } + + remove(len); +} + +EXPORT void RingBufBase::move_in(IndexBase & index, int from, int len) +{ + assert(from >= 0 && from <= index.len()); + assert(len <= index.len() - from); + + if (len < 0) + len = index.len() - from; + + move_in((char *)index.begin() + from, len, nullptr); + index.remove(from, len, nullptr); +} + +EXPORT void RingBufBase::move_out(IndexBase & index, int to, int len) +{ + assert(len <= m_len); + + if (len < 0) + len = m_len; + + void * ptr = index.insert(to, len); + move_out(ptr, len, nullptr); +} diff --git a/src/libaudcore/ringbuf.h b/src/libaudcore/ringbuf.h new file mode 100644 index 0000000..2dd72bd --- /dev/null +++ b/src/libaudcore/ringbuf.h @@ -0,0 +1,172 @@ +/* + * ringbuf.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_RINGBUF_H +#define LIBAUDCORE_RINGBUF_H + +#include <libaudcore/index.h> + +/* + * RingBuf is a lightweight ring buffer class, with the following properties: + * - The base implementation is type-agnostic, so it only needs to be compiled + * once. Type-safety is provided by a thin template subclass. + * - Objects are moved in memory without calling any assignment operator. + * Be careful to use only objects that can handle this. + * - The head and tail pointers within the ring buffer stay aligned as one + * would expect: that is, if data is only written and read in multiples of n + * bytes, and the size of the ring buffer is also a multiple of n bytes, then + * no n-byte block will ever wrap around the end of the ring buffer. The + * alignment of the buffer is reset whenever the buffer becomes empty. + */ + +class RingBufBase +{ +public: + constexpr RingBufBase() : m_data(nullptr), m_size(0), m_offset(0), m_len(0) + { + } + + RingBufBase(RingBufBase && b) + : m_data(b.m_data), m_size(b.m_size), m_offset(b.m_offset), + m_len(b.m_len) + { + b.m_data = nullptr; + b.m_size = 0; + b.m_offset = 0; + b.m_len = 0; + } + + // allocated size of the buffer + int size() const { return m_size; } + + // number of bytes currently used + int len() const { return m_len; } + + // number of bytes that can be read linearly + int linear() const { return aud::min(m_len, m_size - m_offset); } + + void * at(int pos) const + { + return (char *)m_data + (m_offset + pos) % m_size; + } + + void alloc(int size); + void destroy(aud::EraseFunc erase_func); + + void add(int len); // no fill + void remove(int len); // no erase + + void copy_in(const void * from, int len, aud::CopyFunc copy_func); + void move_in(void * from, int len, aud::FillFunc fill_func); + void move_out(void * to, int len, aud::EraseFunc erase_func); + void discard(int len, aud::EraseFunc erase_func); + + void move_in(IndexBase & index, int from, int len); + void move_out(IndexBase & index, int to, int len); + +private: + struct Areas + { + void *area1, *area2; + int len1, len2; + }; + + void get_areas(int pos, int len, Areas & areas); + void do_realloc(int size); + + void * m_data; + int m_size, m_offset, m_len; +}; + +template<class T> +class RingBuf : private RingBufBase +{ +public: + constexpr RingBuf() : RingBufBase() {} + + ~RingBuf() { destroy(); } + + RingBuf(RingBuf && b) : RingBufBase(std::move(b)) {} + RingBuf & operator=(RingBuf && b) + { + return aud::move_assign(*this, std::move(b)); + } + + int size() const { return cooked(RingBufBase::size()); } + int len() const { return cooked(RingBufBase::len()); } + int linear() const { return cooked(RingBufBase::linear()); } + int space() const { return size() - len(); } + + T & operator[](int i) { return *(T *)RingBufBase::at(raw(i)); } + const T & operator[](int i) const + { + return *(const T *)RingBufBase::at(raw(i)); + } + + void alloc(int size) { RingBufBase::alloc(raw(size)); } + void destroy() { RingBufBase::destroy(aud::erase_func<T>()); } + + void copy_in(const T * from, int len) + { + RingBufBase::copy_in(from, raw(len), aud::copy_func<T>()); + } + void move_in(T * from, int len) + { + RingBufBase::move_in(from, raw(len), aud::fill_func<T>()); + } + void move_out(T * to, int len) + { + RingBufBase::move_out(to, raw(len), aud::erase_func<T>()); + } + void discard(int len = -1) + { + RingBufBase::discard(raw(len), aud::erase_func<T>()); + } + + void move_in(Index<T> & index, int from, int len) + { + RingBufBase::move_in(index.base(), raw(from), raw(len)); + } + void move_out(Index<T> & index, int to, int len) + { + RingBufBase::move_out(index.base(), raw(to), raw(len)); + } + + template<class... Args> + T & push(Args &&... args) + { + add(raw(1)); + return *aud::construct<T>::make(at(raw(len() - 1)), + std::forward<Args>(args)...); + } + + T & head() { return *(T *)at(raw(0)); } + + void pop() + { + head().~T(); + remove(raw(1)); + } + +private: + static constexpr int raw(int len) { return len * sizeof(T); } + static constexpr int cooked(int len) { return len / sizeof(T); } +}; + +#endif // LIBAUDCORE_RINGBUF_H diff --git a/src/libaudcore/runtime.cc b/src/libaudcore/runtime.cc new file mode 100644 index 0000000..062cc59 --- /dev/null +++ b/src/libaudcore/runtime.cc @@ -0,0 +1,365 @@ +/* + * runtime.c + * Copyright 2010-2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "runtime.h" + +#include <errno.h> +#include <locale.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <new> + +#ifdef _WIN32 +#include <windows.h> +#endif +#ifdef __APPLE__ +#include <mach-o/dyld.h> +#endif + +#include <glib.h> +#include <libintl.h> + +#include "audstrings.h" +#include "drct.h" +#include "hook.h" +#include "internal.h" +#include "mainloop.h" +#include "output.h" +#include "playlist-internal.h" +#include "plugins-internal.h" +#include "scanner.h" + +#define AUTOSAVE_INTERVAL 300000 /* milliseconds, autosave every 5 minutes */ + +#ifdef WORDS_BIGENDIAN +#define UTF16_NATIVE "UTF-16BE" +#else +#define UTF16_NATIVE "UTF-16LE" +#endif + +#ifdef S_IRGRP +#define DIRMODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) +#else +#define DIRMODE (S_IRWXU) +#endif + +size_t misc_bytes_allocated; + +static bool headless_mode; +static int instance_number = 1; + +#if defined(USE_GTK) && !defined(USE_QT) +static MainloopType mainloop_type = MainloopType::GLib; +#else +static MainloopType mainloop_type = MainloopType::Qt; +#endif + +static aud::array<AudPath, String> aud_paths; + +EXPORT void aud_set_headless_mode(bool headless) { headless_mode = headless; } +EXPORT bool aud_get_headless_mode() { return headless_mode; } + +EXPORT void aud_set_instance(int instance) { instance_number = instance; } +EXPORT int aud_get_instance() { return instance_number; } + +EXPORT void aud_set_mainloop_type(MainloopType type) { mainloop_type = type; } +EXPORT MainloopType aud_get_mainloop_type() { return mainloop_type; } + +static StringBuf get_path_to_self() +{ +#ifdef __linux__ + + StringBuf buf(-1); + int len = readlink("/proc/self/exe", buf, buf.len()); + + if (len < 0) + { + AUDERR("Failed to read /proc/self/exe: %s\n", strerror(errno)); + return StringBuf(); + } + + if (len == buf.len()) + throw std::bad_alloc(); + + buf.resize(len); + return buf; + +#elif defined _WIN32 + + StringBuf buf(-1); + wchar_t * bufw = (wchar_t *)(char *)buf; + int sizew = buf.len() / sizeof(wchar_t); + int lenw = GetModuleFileNameW(nullptr, bufw, sizew); + + if (!lenw) + { + AUDERR("GetModuleFileName failed.\n"); + return StringBuf(); + } + + if (lenw == sizew) + throw std::bad_alloc(); + + buf.resize(lenw * sizeof(wchar_t)); + buf = str_convert(buf, buf.len(), UTF16_NATIVE, "UTF-8"); + return buf.settle(); + +#elif defined __APPLE__ + + StringBuf buf(-1); + uint32_t size = buf.len(); + + if (_NSGetExecutablePath(buf, &size) < 0) + throw std::bad_alloc(); + + buf.resize(strlen(buf)); + return buf; + +#else + + return StringBuf(); + +#endif +} + +static String relocate_path(const char * path, const char * from, + const char * to) +{ + int oldlen = strlen(from); + int newlen = strlen(to); + + if (oldlen && from[oldlen - 1] == G_DIR_SEPARATOR) + oldlen--; + if (newlen && to[newlen - 1] == G_DIR_SEPARATOR) + newlen--; + +#ifdef _WIN32 + if (strcmp_nocase(path, from, oldlen) || + (path[oldlen] && path[oldlen] != G_DIR_SEPARATOR)) +#else + if (strncmp(path, from, oldlen) || + (path[oldlen] && path[oldlen] != G_DIR_SEPARATOR)) +#endif + return String(path); + + return String(str_printf("%.*s%s", newlen, to, path + oldlen)); +} + +static void set_default_paths() +{ + aud_paths[AudPath::BinDir] = String(INSTALL_BINDIR); + aud_paths[AudPath::DataDir] = String(INSTALL_DATADIR); + aud_paths[AudPath::PluginDir] = String(INSTALL_PLUGINDIR); + aud_paths[AudPath::LocaleDir] = String(INSTALL_LOCALEDIR); + aud_paths[AudPath::DesktopFile] = String(INSTALL_DESKTOPFILE); + aud_paths[AudPath::IconFile] = String(INSTALL_ICONFILE); +} + +static void set_install_paths() +{ + StringBuf bindir = filename_normalize(str_copy(INSTALL_BINDIR)); + StringBuf datadir = filename_normalize(str_copy(INSTALL_DATADIR)); + StringBuf plugindir = filename_normalize(str_copy(INSTALL_PLUGINDIR)); + StringBuf localedir = filename_normalize(str_copy(INSTALL_LOCALEDIR)); + StringBuf desktopfile = filename_normalize(str_copy(INSTALL_DESKTOPFILE)); + StringBuf iconfile = filename_normalize(str_copy(INSTALL_ICONFILE)); + + StringBuf from = str_copy(bindir); + + /* get path to current executable */ + StringBuf to = get_path_to_self(); + + if (!to) + { + set_default_paths(); + return; + } + + to = filename_normalize(std::move(to)); + + const char * base = last_path_element(to); + + if (!base) + { + set_default_paths(); + return; + } + + cut_path_element(to, base - to); + + /* trim trailing path elements common to old and new paths */ + /* at the end, the old and new installation prefixes are left */ + const char *a, *b; + while ((a = last_path_element(from)) && (b = last_path_element(to)) && +#ifdef _WIN32 + !strcmp_nocase(a, b)) +#else + !strcmp(a, b)) +#endif + { + cut_path_element(from, a - from); + cut_path_element(to, b - to); + } + + /* replace old prefix with new one in each path */ + aud_paths[AudPath::BinDir] = relocate_path(bindir, from, to); + aud_paths[AudPath::DataDir] = relocate_path(datadir, from, to); + aud_paths[AudPath::PluginDir] = relocate_path(plugindir, from, to); + aud_paths[AudPath::LocaleDir] = relocate_path(localedir, from, to); + aud_paths[AudPath::DesktopFile] = relocate_path(desktopfile, from, to); + aud_paths[AudPath::IconFile] = relocate_path(iconfile, from, to); +} + +static void set_config_paths() +{ + const char * xdg_config_home = g_get_user_config_dir(); + StringBuf name = (instance_number == 1) + ? str_copy("audacious") + : str_printf("audacious-%d", instance_number); + + aud_paths[AudPath::UserDir] = + String(filename_build({xdg_config_home, name})); + aud_paths[AudPath::PlaylistDir] = + String(filename_build({aud_paths[AudPath::UserDir], "playlists"})); + + if (g_mkdir_with_parents(aud_paths[AudPath::PlaylistDir], DIRMODE) < 0) + AUDERR("Failed to create %s: %s\n", + (const char *)aud_paths[AudPath::PlaylistDir], strerror(errno)); + +#ifdef _WIN32 + /* set some UNIX-style environment variables */ + g_setenv("HOME", g_get_home_dir(), true); + g_setenv("XDG_CONFIG_HOME", xdg_config_home, true); + g_setenv("XDG_DATA_HOME", g_get_user_data_dir(), true); + g_setenv("XDG_CACHE_HOME", g_get_user_cache_dir(), true); +#endif +} + +EXPORT const char * aud_get_path(AudPath id) +{ + if (!aud_paths[id]) + { + if (id <= AudPath::IconFile) + set_install_paths(); + else + set_config_paths(); + } + + return aud_paths[id]; +} + +EXPORT void aud_init_i18n() +{ + const char * localedir = aud_get_path(AudPath::LocaleDir); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, localedir); + bind_textdomain_codeset(PACKAGE, "UTF-8"); + bindtextdomain(PACKAGE "-plugins", localedir); + bind_textdomain_codeset(PACKAGE "-plugins", "UTF-8"); + textdomain(PACKAGE); +} + +EXPORT void aud_init() +{ + g_thread_pool_set_max_idle_time(100); + + config_load(); + + chardet_init(); + eq_init(); + output_init(); + playlist_init(); + + start_plugins_one(); + + record_init(); + scanner_init(); + load_playlists(); +} + +static void do_autosave(void *) +{ + hook_call("config save", nullptr); + save_playlists(false); + plugin_registry_save(); + config_save(); +} + +EXPORT void aud_run() +{ + /* playlist_enable_scan() should be after aud_resume(); the intent is to + * avoid scanning until the currently playing entry is known, at which time + * it can be scanned more efficiently (album art read in the same pass). */ + playlist_enable_scan(true); + playlist_clear_updates(); + start_plugins_two(); + + static QueuedFunc autosave; + autosave.start(AUTOSAVE_INTERVAL, do_autosave, nullptr); + + /* calls "config save" before returning */ + interface_run(); + + autosave.stop(); + + stop_plugins_two(); + playlist_enable_scan(false); +} + +EXPORT void aud_cleanup() +{ + save_playlists(true); + + aud_drct_stop(); + playback_stop(true); + + adder_cleanup(); + scanner_cleanup(); + record_cleanup(); + + stop_plugins_one(); + + art_cleanup(); + chardet_cleanup(); + eq_cleanup(); + output_cleanup(); + playlist_end(); + + event_queue_cancel_all(); + hook_cleanup(); + timer_cleanup(); + + config_save(); + config_cleanup(); +} + +EXPORT void aud_leak_check() +{ + for (String & path : aud_paths) + path = String(); + + string_leak_check(); + + if (misc_bytes_allocated) + AUDWARN("Bytes allocated at exit: %ld\n", (long)misc_bytes_allocated); +} diff --git a/src/libaudcore/runtime.h b/src/libaudcore/runtime.h new file mode 100644 index 0000000..244eacd --- /dev/null +++ b/src/libaudcore/runtime.h @@ -0,0 +1,202 @@ +/* + * runtime.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_RUNTIME_H +#define LIBAUDCORE_RUNTIME_H + +#include <libaudcore/objects.h> + +enum class AudPath +{ + BinDir, + DataDir, + PluginDir, + LocaleDir, + DesktopFile, + IconFile, + UserDir, + PlaylistDir, + count +}; + +enum class MainloopType +{ + GLib, + Qt +}; + +enum class OutputReset +{ + EffectsOnly, + ReopenStream, + ResetPlugin +}; + +enum class OutputStream +{ + AsDecoded, + AfterReplayGain, + AfterEffects, + AfterEqualizer +}; + +enum class ReplayGainMode +{ + Track, + Album, + Automatic +}; + +namespace audlog +{ +enum Level +{ + Debug, + Info, + Warning, + Error +}; + +typedef void (*Handler)(Level level, const char * file, int line, + const char * func, const char * message); + +void set_stderr_level(Level level); +void subscribe(Handler handler, Level level); +void unsubscribe(Handler handler); + +#ifdef _WIN32 +void log(Level level, const char * file, int line, const char * func, + const char * format, ...) + __attribute__((__format__(gnu_printf, 5, 6))); +#else +void log(Level level, const char * file, int line, const char * func, + const char * format, ...) + __attribute__((__format__(__printf__, 5, 6))); +#endif + +const char * get_level_name(Level level); +} // namespace audlog + +#define AUDERR(...) \ + do \ + { \ + audlog::log(audlog::Error, __FILE__, __LINE__, __FUNCTION__, \ + __VA_ARGS__); \ + } while (0) +#define AUDWARN(...) \ + do \ + { \ + audlog::log(audlog::Warning, __FILE__, __LINE__, __FUNCTION__, \ + __VA_ARGS__); \ + } while (0) +#define AUDINFO(...) \ + do \ + { \ + audlog::log(audlog::Info, __FILE__, __LINE__, __FUNCTION__, \ + __VA_ARGS__); \ + } while (0) +#define AUDDBG(...) \ + do \ + { \ + audlog::log(audlog::Debug, __FILE__, __LINE__, __FUNCTION__, \ + __VA_ARGS__); \ + } while (0) + +const char * aud_get_path(AudPath id); + +void aud_set_headless_mode(bool headless); +bool aud_get_headless_mode(); + +// Note that the UserDir and PlaylistDir paths vary depending on the instance +// number. Therefore, calling aud_set_instance() after these paths have been +// referenced, or after aud_init(), is an error. +void aud_set_instance(int instance); +int aud_get_instance(); + +void aud_set_mainloop_type(MainloopType type); +MainloopType aud_get_mainloop_type(); + +void aud_init_i18n(); + +void aud_config_set_defaults(const char * section, + const char * const * entries); + +void aud_set_str(const char * section, const char * name, const char * value); +String aud_get_str(const char * section, const char * name); +void aud_set_bool(const char * section, const char * name, bool value); +bool aud_get_bool(const char * section, const char * name); +void aud_toggle_bool(const char * section, const char * name); +void aud_set_int(const char * section, const char * name, int value); +int aud_get_int(const char * section, const char * name); +void aud_set_double(const char * section, const char * name, double value); +double aud_get_double(const char * section, const char * name); + +/* overloads for main ("audacious") config section */ +static inline void aud_set_str(const char * name, const char * value) +{ + aud_set_str(nullptr, name, value); +} +static inline String aud_get_str(const char * name) +{ + return aud_get_str(nullptr, name); +} +static inline void aud_set_bool(const char * name, bool value) +{ + aud_set_bool(nullptr, name, value); +} +static inline bool aud_get_bool(const char * name) +{ + return aud_get_bool(nullptr, name); +} +static inline void aud_toggle_bool(const char * name) +{ + aud_toggle_bool(nullptr, name); +} +static inline void aud_set_int(const char * name, int value) +{ + aud_set_int(nullptr, name, value); +} +static inline int aud_get_int(const char * name) +{ + return aud_get_int(nullptr, name); +} +static inline void aud_set_double(const char * name, double value) +{ + aud_set_double(nullptr, name, value); +} +static inline double aud_get_double(const char * name) +{ + return aud_get_double(nullptr, name); +} + +void aud_init(); +void aud_resume(); +void aud_run(); +void aud_quit(); +void aud_cleanup(); + +void aud_leak_check(); + +String aud_history_get(int entry); +void aud_history_add(const char * path); +void aud_history_clear(); + +void aud_output_reset(OutputReset type); + +#endif diff --git a/src/libaudcore/scanner.cc b/src/libaudcore/scanner.cc new file mode 100644 index 0000000..2ad2ebc --- /dev/null +++ b/src/libaudcore/scanner.cc @@ -0,0 +1,128 @@ +/* + * scanner.c + * Copyright 2012-2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "scanner.h" + +#include <glib.h> /* for GThreadPool */ + +#include "audstrings.h" +#include "cue-cache.h" +#include "i18n.h" +#include "internal.h" +#include "plugins.h" +#include "probe.h" +#include "tuple.h" +#include "vfs.h" + +static GThreadPool * pool; + +ScanRequest::ScanRequest(const String & filename, int flags, Callback callback, + PluginHandle * decoder, Tuple && tuple) + : filename(filename), flags(flags), callback(callback), decoder(decoder), + tuple(std::move(tuple)), ip(nullptr) +{ + /* If this is a cuesheet entry (and it has not already been loaded), capture + * a reference to the cache immediately. During a playlist scan, requests + * have overlapping lifecycles--each new ScanRequest is created by the + * callback of the previous request--so the cached cuesheet persists as long + * as consecutive playlist entries reference it. */ + if (!this->tuple.valid() && is_cuesheet_entry(filename)) + cue_cache.capture(new CueCacheRef(strip_subtune(filename))); +} + +void ScanRequest::read_cuesheet_entry() +{ + for (auto & item : cue_cache->load()) + { + if (item.filename == filename) + { + decoder = item.decoder; + tuple = item.tuple.ref(); + break; + } + } +} + +void ScanRequest::run() +{ + /* load cuesheet entry (possibly cached) */ + if (cue_cache) + read_cuesheet_entry(); + + /* for a cuesheet entry, determine the source filename */ + String audio_file = tuple.get_str(Tuple::AudioFile); + if (!audio_file) + audio_file = filename; + + bool need_tuple = (flags & SCAN_TUPLE) && !tuple.valid(); + bool need_image = (flags & SCAN_IMAGE); + + if (!decoder) + decoder = aud_file_find_decoder(audio_file, false, file, &error); + if (!decoder) + goto err; + + if (need_tuple || need_image) + { + if (!(ip = load_input_plugin(decoder, &error))) + goto err; + + Tuple dummy_tuple; + /* don't overwrite tuple if already valid (e.g. from a cuesheet) */ + Tuple & rtuple = need_tuple ? tuple : dummy_tuple; + Index<char> * pimage = need_image ? &image_data : nullptr; + if (!aud_file_read_tag(audio_file, decoder, file, rtuple, pimage, + &error)) + goto err; + + if (need_image && !image_data.len()) + image_file = art_search(audio_file); + } + + /* rewind/reopen the input file */ + if ((flags & SCAN_FILE)) + open_input_file(audio_file, "r", ip, file, &error); + else + { + err: + /* close file if not needed or if an error occurred */ + file = VFSFile(); + } + + callback(this); +} + +static void scan_worker(void * data, void *) +{ + ((ScanRequest *)data)->run(); + delete (ScanRequest *)data; +} + +void scanner_init() +{ + pool = + g_thread_pool_new(scan_worker, nullptr, SCAN_THREADS, false, nullptr); +} + +void scanner_request(ScanRequest * request) +{ + g_thread_pool_push(pool, request, nullptr); +} + +void scanner_cleanup() { g_thread_pool_free(pool, false, true); } diff --git a/src/libaudcore/scanner.h b/src/libaudcore/scanner.h new file mode 100644 index 0000000..0b6ad30 --- /dev/null +++ b/src/libaudcore/scanner.h @@ -0,0 +1,71 @@ +/* + * scanner.h + * Copyright 2012-2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_SCANNER_H +#define LIBAUDCORE_SCANNER_H + +#include "cue-cache.h" +#include "index.h" +#include "objects.h" +#include "tuple.h" +#include "vfs.h" + +class InputPlugin; +class PluginHandle; + +#define SCAN_TUPLE (1 << 0) +#define SCAN_IMAGE (1 << 1) +#define SCAN_FILE (1 << 2) + +#define SCAN_THREADS 2 + +struct ScanRequest +{ + typedef void (*Callback)(ScanRequest * request); + + const String filename; + const int flags; + const Callback callback; + + PluginHandle * decoder; + Tuple tuple; + + InputPlugin * ip; + VFSFile file; + + Index<char> image_data; + String image_file; + String error; + + ScanRequest(const String & filename, int flags, Callback callback, + PluginHandle * decoder = nullptr, Tuple && tuple = Tuple()); + + void run(); + +private: + SmartPtr<CueCacheRef> cue_cache; + + void read_cuesheet_entry(); +}; + +void scanner_init(); +void scanner_request(ScanRequest * request); +void scanner_cleanup(); + +#endif diff --git a/src/libaudcore/stringbuf.cc b/src/libaudcore/stringbuf.cc new file mode 100644 index 0000000..0b50ea2 --- /dev/null +++ b/src/libaudcore/stringbuf.cc @@ -0,0 +1,281 @@ +/* + * stringbuf.cc + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <pthread.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <new> + +#include "objects.h" +#include "threads.h" + +#ifdef _WIN32 +#include <windows.h> +#else +#include <sys/mman.h> +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif +#endif + +struct StringHeader +{ + StringHeader *next, *prev; + int len; +}; + +struct StringStack +{ + static constexpr int Size = 1048576; // 1 MB + + StringHeader * top; + char buf[Size - sizeof top]; +}; + +static constexpr intptr_t align(intptr_t ptr, intptr_t size) +{ + return (ptr + (size - 1)) / size * size; +} + +static StringHeader * align_after(StringStack * stack, + StringHeader * prev_header) +{ + char * base; + if (prev_header) + base = + (char *)prev_header + sizeof(StringHeader) + prev_header->len + 1; + else + base = stack->buf; + + return (StringHeader *)align((intptr_t)base, alignof(StringHeader)); +} + +static pthread_key_t key; +static std::once_flag once; + +#ifdef _WIN32 +static HANDLE mapping; +#endif + +static void free_stack(void * stack) +{ + if (stack) +#ifdef _WIN32 + UnmapViewOfFile(stack); +#else + munmap(stack, sizeof(StringStack)); +#endif +} + +static void make_key() +{ + pthread_key_create(&key, free_stack); + +#ifdef _WIN32 + mapping = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, + 0, sizeof(StringStack), nullptr); + + if (!mapping) + throw std::bad_alloc(); +#endif +} + +static StringStack * get_stack() +{ + std::call_once(once, make_key); + + StringStack * stack = (StringStack *)pthread_getspecific(key); + + if (!stack) + { +#ifdef _WIN32 + stack = (StringStack *)MapViewOfFile(mapping, FILE_MAP_COPY, 0, 0, + sizeof(StringStack)); + + if (!stack) + throw std::bad_alloc(); +#else + stack = (StringStack *)mmap(nullptr, sizeof(StringStack), + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + if (stack == MAP_FAILED) + throw std::bad_alloc(); +#endif + + stack->top = nullptr; + pthread_setspecific(key, stack); + } + + return stack; +} + +EXPORT void StringBuf::resize(int len) +{ + if (!stack) + stack = get_stack(); + + StringHeader * header = nullptr; + bool need_alloc = true; + + if (m_data) + { + header = (StringHeader *)(m_data - sizeof(StringHeader)); + + /* check if there is enough space in the current location */ + char * limit = header->next ? (char *)header->next + : (char *)stack + sizeof(StringStack); + int max_len = limit - 1 - m_data; + + if ((len < 0 && !header->next) || (len >= 0 && len < max_len)) + { + m_len = header->len = (len < 0) ? max_len : len; + need_alloc = false; + } + } + + if (need_alloc) + { + /* allocate a new string at the top of the stack */ + StringHeader * new_header = align_after(stack, stack->top); + char * new_data = (char *)new_header + sizeof(StringHeader); + char * limit = (char *)stack + sizeof(StringStack); + int max_len = limit - 1 - new_data; + + if (max_len < aud::max(len, 0)) + throw std::bad_alloc(); + + int new_len = (len < 0) ? max_len : len; + + if (stack->top) + stack->top->next = new_header; + + new_header->prev = stack->top; + new_header->next = nullptr; + new_header->len = new_len; + + stack->top = new_header; + + /* move the old data, if any */ + if (m_data) + { + int bytes_to_copy = aud::min(m_len, new_len); + memcpy(new_data, m_data, bytes_to_copy); + + if (header->prev) + header->prev->next = header->next; + + /* we know header != stack->top */ + header->next->prev = header->prev; + } + + m_data = new_data; + m_len = new_len; + } + + /* Null-terminate the string except when the maximum length was requested + * (to avoid paging in the entire 1 MB stack prematurely). The caller is + * expected to follow up with a more realistic resize() in this case. */ + if (len >= 0) + m_data[len] = 0; +} + +EXPORT StringBuf::~StringBuf() +{ + if (m_data) + { + auto header = (StringHeader *)(m_data - sizeof(StringHeader)); + + if (header->prev) + header->prev->next = header->next; + + if (header == stack->top) + stack->top = header->prev; + else + header->next->prev = header->prev; + } +} + +EXPORT void StringBuf::steal(StringBuf && other) +{ + (*this = std::move(other)).settle(); +} + +EXPORT StringBuf && StringBuf::settle() +{ + if (m_data) + { + /* collapse any space preceding this string */ + auto header = (StringHeader *)(m_data - sizeof(StringHeader)); + StringHeader * new_header = align_after(stack, header->prev); + + if (new_header != header) + { + if (header->prev) + header->prev->next = new_header; + + if (header == stack->top) + stack->top = new_header; + else + header->next->prev = new_header; + + memmove(new_header, header, sizeof(StringHeader) + m_len + 1); + m_data = (char *)new_header + sizeof(StringHeader); + } + } + + return std::move(*this); +} + +EXPORT void StringBuf::combine(StringBuf && other) +{ + if (!other.m_data) + return; + + insert(m_len, other.m_data, other.m_len); + other = StringBuf(); + settle(); +} + +EXPORT char * StringBuf::insert(int pos, const char * s, int len) +{ + int len0 = m_len; + + if (pos < 0) + pos = len0; + if (len < 0) + len = strlen(s); + + resize(len0 + len); + memmove(m_data + pos + len, m_data + pos, len0 - pos); + + if (s) + memcpy(m_data + pos, s, len); + + return m_data + pos; +} + +EXPORT void StringBuf::remove(int pos, int len) +{ + int after = m_len - pos - len; + memmove(m_data + pos, m_data + pos + len, after); + resize(pos + after); +} diff --git a/src/libaudcore/strpool.cc b/src/libaudcore/strpool.cc new file mode 100644 index 0000000..96edb99 --- /dev/null +++ b/src/libaudcore/strpool.cc @@ -0,0 +1,201 @@ +/* + * strpool.c + * Copyright 2011-2017 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stdlib.h> +#include <string.h> + +#include "audstrings.h" +#include "internal.h" +#include "multihash.h" +#include "objects.h" +#include "runtime.h" + +#ifdef VALGRIND_FRIENDLY + +#include <glib.h> + +EXPORT char * String::raw_get(const char * str) { return g_strdup(str); } +EXPORT char * String::raw_ref(const char * str) { return g_strdup(str); } +EXPORT void String::raw_unref(char * str) { g_free(str); } + +void string_leak_check() {} + +EXPORT unsigned String::raw_hash(const char * str) +{ + return str_calc_hash(str); +} +EXPORT bool String::raw_equal(const char * str1, const char * str2) +{ + return !strcmp_safe(str1, str2); +} + +#else // ! VALGRIND_FRIENDLY + +struct StrNode : public MultiHash::Node +{ + /* the characters of the string immediately follow the StrNode struct */ + const char * str() const + { + return reinterpret_cast<const char *>(this + 1); + } + char * str() { return reinterpret_cast<char *>(this + 1); } + + static const StrNode * of(const char * s) + { + return reinterpret_cast<const StrNode *>(s) - 1; + } + static StrNode * of(char * s) { return reinterpret_cast<StrNode *>(s) - 1; } + + static StrNode * create(const char * s) + { + auto size = sizeof(StrNode) + strlen(s) + 1; + auto node = static_cast<StrNode *>(malloc(size)); + if (!node) + throw std::bad_alloc(); + + strcpy(node->str(), s); + return node; + } + + bool match(const char * data) const + { + return data == str() || !strcmp(data, str()); + } +}; + +static MultiHash_T<StrNode, char> strpool_table; + +struct Getter +{ + StrNode * node; + + StrNode * add(const char * data) + { + node = StrNode::create(data); + node->refs = 1; + return node; + } + + bool found(StrNode * node_) + { + node = node_; + __sync_fetch_and_add(&node->refs, 1); + return false; + } +}; + +struct Remover +{ + StrNode * add(const char *) { return nullptr; } + + bool found(StrNode * node) + { + if (!__sync_bool_compare_and_swap(&node->refs, 1, 0)) + return false; + + free(node); + return true; + } +}; + +/* If the pool contains a copy of <str>, increments its reference count. + * Otherwise, adds a copy of <str> to the pool with a reference count of one. + * In either case, returns the copy. Because this copy may be shared by other + * parts of the code, it should not be modified. If <str> is null, simply + * returns null with no side effects. */ +EXPORT char * String::raw_get(const char * str) +{ + if (!str) + return nullptr; + + Getter op; + strpool_table.lookup(str, str_calc_hash(str), op); + return op.node->str(); +} + +/* Increments the reference count of <str>, where <str> is the address of a + * string already in the pool. Faster than calling raw_get() a second time. + * Returns <str> for convenience. If <str> is null, simply returns null with no + * side effects. */ +EXPORT char * String::raw_ref(const char * str_) +{ + auto str = const_cast<char *>(str_); + if (!str) + return nullptr; + + auto node = StrNode::of(str); + __sync_fetch_and_add(&node->refs, 1); + return str; +} + +/* Decrements the reference count of <str>, where <str> is the address of a + * string in the pool. If the reference count drops to zero, releases the + * memory used by <str>. If <str> is null, simply returns null with no side + * effects. */ +EXPORT void String::raw_unref(char * str) +{ + if (!str) + return; + + auto node = StrNode::of(str); + + while (1) + { + unsigned refs = __sync_fetch_and_add(&node->refs, 0); + if (refs > 1) + { + if (__sync_bool_compare_and_swap(&node->refs, refs, refs - 1)) + break; + } + else + { + Remover op; + int status = strpool_table.lookup(str, node->hash, op); + if (!(status & MultiHash::Found)) + throw std::bad_alloc(); + if (status & MultiHash::Removed) + break; + } + } +} + +void string_leak_check() +{ + strpool_table.iterate([](const StrNode * node) { + AUDWARN("String leaked: %s\n", node->str()); + return false; + }); +} + +/* Returns the cached hash value of a pooled string (or 0 for null). */ +EXPORT unsigned String::raw_hash(const char * str) +{ + return str ? StrNode::of(str)->hash : 0; +} + +/* Checks whether two pooled strings are equal. Since the pool never contains + * duplicate strings, this is a simple pointer comparison and thus much faster + * than strcmp(). null is considered equal to null but not equal to any string. + */ +EXPORT bool String::raw_equal(const char * str1, const char * str2) +{ + return str1 == str2; +} + +#endif // ! VALGRIND_FRIENDLY diff --git a/src/libaudcore/templates.h b/src/libaudcore/templates.h new file mode 100644 index 0000000..e5f03ec --- /dev/null +++ b/src/libaudcore/templates.h @@ -0,0 +1,393 @@ +/* + * templates.h + * Copyright 2014-2019 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_TEMPLATES_H +#define LIBAUDCORE_TEMPLATES_H + +#include <new> +#include <type_traits> +#include <utility> + +// #undef POSIX and Windows macros to avoid name conflicts +#undef abs +#undef min +#undef max + +namespace aud +{ + +// Utility functions +// ================= + +// minimum of two numbers +template<class T> +constexpr T min(T a, T b) +{ + return a < b ? a : b; +} + +// maximum of two numbers +template<class T> +constexpr T max(T a, T b) +{ + return a > b ? a : b; +} + +// make sure a number is within the given range +template<class T> +constexpr T clamp(T x, T low, T high) +{ + return min(max(x, low), high); +} + +// absolute value +template<class T> +constexpr T abs(T x) +{ + return x < 0 ? -x : x; +} + +// change the sign of x to the sign of s +template<class T> +constexpr T chsign(T x, T s) +{ + return (x < 0) ^ (s < 0) ? -x : x; +} + +// integer division with rounding +template<class T> +constexpr T rdiv(T x, T y) +{ + return (x + chsign(y / 2, x)) / y; +} + +// convert integer from one scale to another, with rounding +template<class T> +constexpr T rescale(T x, T old_scale, T new_scale) +{ + return rdiv(x * new_scale, old_scale); +} + +// number of characters needed to represent an integer (including minus sign) +template<class T> +constexpr T n_digits(T x) +{ + return x < 0 ? 1 + n_digits(-x) : x < 10 ? 1 : 1 + n_digits(x / 10); +} + +// number of elements in an array +template<class T, int N> +constexpr int n_elems(const T (&)[N]) +{ + return N; +} + +// Casts for storing various data in a void pointer +// ================================================ + +template<class T> +inline void * to_ptr(T t) +{ + union { + void * v; + T t; + } u = {nullptr}; + static_assert(sizeof u == sizeof(void *), + "Type cannot be stored in a pointer"); + u.t = t; + return u.v; +} + +template<class T> +inline T from_ptr(void * v) +{ + union { + void * v; + T t; + } u = {v}; + static_assert(sizeof u == sizeof(void *), + "Type cannot be stored in a pointer"); + return u.t; +} + +// Move-assignment implemented via move-constructor +// ================================================ + +template<class T> +T & move_assign(T & a, T && b) +{ + if (&a != &b) + { + a.~T(); + new (&a) T(std::move(b)); + } + return a; +} + +// Function wrappers (or "casts") for interaction with C-style APIs +// ================================================================ + +template<class T> +void delete_obj(void * obj) +{ + (void)sizeof(T); + delete (T *)obj; +} + +template<class T> +void delete_typed(T * obj) +{ + (void)sizeof(T); + delete obj; +} + +template<class T, void (*func)(void *)> +void typed_func(T * obj) +{ + func(obj); +} + +template<class T, void (T::*func)()> +static void obj_member(void * obj) +{ + (((T *)obj)->*func)(); +} +template<class T, void (T::*func)() const> +static void obj_member(void * obj) +{ + (((T *)obj)->*func)(); +} + +// Class which provides scope-based "ownership" of an object +// (similar to std::unique_lock, but more flexible) +// ========================================================= + +template<class T, void (T::*acquire)(), void (T::*release)()> +class owner +{ +public: + explicit owner(T * obj = nullptr) : m_obj(obj) + { + if (m_obj) + (m_obj->*acquire)(); + } + ~owner() + { + if (m_obj) + (m_obj->*release)(); + } + + owner(owner && b) : m_obj(b.m_obj) { b.m_obj = nullptr; } + owner & operator=(owner && b) { return move_assign(*this, std::move(b)); } + +private: + T * m_obj; +}; + +// Wrapper class allowing enumerations to be used as array indexes; +// the enumeration must begin with zero and have a "count" constant +// ================================================================ + +template<class T, class V> +struct array +{ + // cannot use std::forward here; it is not constexpr until C++14 + template<class... Args> + constexpr array(Args &&... args) : vals{static_cast<Args &&>(args)...} + { + } + + // Due to GCC bug #63707, the forwarding constructor given above cannot be + // used to initialize the array when V is a class with no copy constructor. + // As a very limited workaround, provide a second constructor which can be + // used to initialize the array to default values in this case. + constexpr array() : vals() {} + + constexpr const V & operator[](T t) const { return vals[(int)t]; } + constexpr const V * begin() const { return vals; } + constexpr const V * end() const { return vals + (int)T::count; } + V & operator[](T t) { return vals[(int)t]; } + V * begin() { return vals; } + V * end() { return vals + (int)T::count; } + +private: + V vals[(int)T::count]; +}; + +// Wrapper class allowing enumerations to be used in range-based for loops +// ======================================================================= + +template<class T, T first = (T)0, T last = (T)((int)T::count - 1)> +struct range +{ + struct iter + { + T v; + constexpr T operator*() const { return v; } + constexpr bool operator!=(iter other) const { return v != other.v; } + void operator++() { v = (T)((int)v + 1); } + }; + + static constexpr iter begin() { return {first}; } + static constexpr iter end() { return {(T)((int)last + 1)}; } +}; + +// Replacement for std::allocator::construct, which also supports aggregate +// initialization. For background, see: +// http://cplusplus.github.io/LWG/lwg-active.html#2089 +// ======================================================================== + +// class constructor proxy +template<class T, bool aggregate> +struct construct_base +{ + template<class... Args> + static T * make(void * loc, Args &&... args) + { + return new (loc) T(std::forward<Args>(args)...); + } +}; + +// aggregate constructor proxy +template<class T> +struct construct_base<T, true> +{ + template<class... Args> + static T * make(void * loc, Args &&... args) + { + return new (loc) T{std::forward<Args>(args)...}; + } +}; + +// generic constructor proxy +template<class T> +struct construct +{ + template<class... Args> + static T * make(void * loc, Args &&... args) + { + constexpr bool aggregate = !std::is_constructible<T, Args &&...>::value; + return construct_base<T, aggregate>::make(loc, + std::forward<Args>(args)...); + } +}; + +// Convert an integer constant to a string at compile-time; can be used for +// #defines, enums, constexpr calculations, etc. +// ======================================================================== + +// "metaprogramming" string type: each different string is a unique type +template<char... args> +struct metastring +{ + char data[sizeof...(args) + 1] = {args..., '\0'}; +}; + +// recursive number-printing template, general case (three or more digits) +template<int size, int x, char... args> +struct numeric_builder +{ + typedef typename numeric_builder<size - 1, x / 10, '0' + abs(x) % 10, + args...>::type type; +}; + +// special case for two digits; minus sign is handled here +template<int x, char... args> +struct numeric_builder<2, x, args...> +{ + typedef metastring < + x<0 ? '-' : '0' + x / 10, '0' + abs(x) % 10, args...> type; +}; + +// special case for one digit (positive numbers only) +template<int x, char... args> +struct numeric_builder<1, x, args...> +{ + typedef metastring<'0' + x, args...> type; +}; + +// convenience wrapper for numeric_builder +template<int x> +class numeric_string +{ +private: + // generate a unique string type representing this number + typedef typename numeric_builder<n_digits(x), x>::type type; + + // declare a static string of that type (instantiated later at file scope) + static constexpr type value{}; + +public: + // pointer to the instantiated string + static constexpr const char * str = value.data; +}; + +// instantiate numeric_string::value as needed for different numbers +template<int x> +constexpr typename numeric_string<x>::type numeric_string<x>::value; + +// Functions for creating/copying/destroying objects en masse; +// these will be nullptr for basic types (use memset/memcpy instead) +// ================================================================= + +typedef void (*FillFunc)(void * data, int len); +typedef void (*CopyFunc)(const void * from, void * to, int len); +typedef void (*EraseFunc)(void * data, int len); + +template<class T> +static constexpr FillFunc fill_func() +{ + return std::is_trivial<T>::value ? (FillFunc) nullptr + : [](void * data, int len) { + T * iter = (T *)data; + T * end = (T *)((char *)data + len); + while (iter < end) + new (iter++) T(); + }; +} + +template<class T> +static constexpr CopyFunc copy_func() +{ + return std::is_trivial<T>::value + ? (CopyFunc) nullptr + : [](const void * from, void * to, int len) { + const T * src = (const T *)from; + T * dest = (T *)to; + T * end = (T *)((char *)to + len); + while (dest < end) + new (dest++) T(*src++); + }; +} + +template<class T> +static constexpr EraseFunc erase_func() +{ + return std::is_trivial<T>::value ? (EraseFunc) nullptr + : [](void * data, int len) { + T * iter = (T *)data; + T * end = (T *)((char *)data + len); + while (iter < end) + (*iter++).~T(); + }; +} + +} // namespace aud + +#endif // LIBAUDCORE_TEMPLATES_H diff --git a/src/libaudcore/tests/Makefile b/src/libaudcore/tests/Makefile new file mode 100644 index 0000000..27621d1 --- /dev/null +++ b/src/libaudcore/tests/Makefile @@ -0,0 +1,41 @@ +all: test test-mainloop + +SRCS = ../audio.cc \ + ../audstrings.cc \ + ../charset.cc \ + ../hook.cc \ + ../index.cc \ + ../logger.cc \ + ../mainloop.cc \ + ../multihash.cc \ + ../ringbuf.cc \ + ../stringbuf.cc \ + ../strpool.cc \ + ../tinylock.cc \ + ../tuple.cc \ + ../tuple-compiler.cc \ + ../util.cc \ + stubs.cc + +FLAGS = -I.. -I../.. -DEXPORT= -DPACKAGE=\"audacious\" -DICONV_CONST= \ + $(shell pkg-config --cflags --libs glib-2.0) \ + -std=c++11 -Wall -g -O0 -fno-elide-constructors \ + -fprofile-arcs -ftest-coverage -pthread + +test: ${SRCS} test.cc + g++ ${SRCS} test.cc ${FLAGS} -o test + +test-mainloop: ${SRCS} test-mainloop.cc + g++ ${SRCS} test-mainloop.cc ${FLAGS} -DUSE_QT -fPIC \ + $(shell pkg-config --cflags --libs Qt5Core) \ + -o test-mainloop + +cov: all + rm -f *.gcda + ./test + ./test-mainloop + ./test-mainloop --qt + gcov --object-directory . ${SRCS} ${MAINLOOP_SRCS} + +clean: + rm -f test test-mainloop *.gcno *.gcda *.gcov diff --git a/src/libaudcore/tests/stubs.cc b/src/libaudcore/tests/stubs.cc new file mode 100644 index 0000000..da71d12 --- /dev/null +++ b/src/libaudcore/tests/stubs.cc @@ -0,0 +1,14 @@ +#include "internal.h" +#include "vfs.h" + +extern "C" const char * libguess_determine_encoding (const char *, int, const char *) + { return nullptr; } + +bool aud_get_bool (const char *, const char *) + { return false; } +String aud_get_str (const char *, const char *) + { return String (""); } +String VFSFile::get_metadata (const char *) + { return String (); } + +size_t misc_bytes_allocated; diff --git a/src/libaudcore/tests/test-mainloop.cc b/src/libaudcore/tests/test-mainloop.cc new file mode 100644 index 0000000..418c7dc --- /dev/null +++ b/src/libaudcore/tests/test-mainloop.cc @@ -0,0 +1,140 @@ +/* + * test-mainloop.cc - Main loop test for libaudcore + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "mainloop.h" +#include "runtime.h" +#include "threads.h" + +#include <assert.h> +#include <stdio.h> +#include <string.h> + +static bool use_qt = false; + +MainloopType aud_get_mainloop_type () +{ + return use_qt ? MainloopType::Qt : MainloopType::GLib; +} + +static QueuedFunc counters[70]; +static QueuedFunc timer, delayed; + +static int count; +static std::thread::id main_thread; + +static void never_called (void * data) +{ + bool called = true; + assert (! called); +} + +static void count_up (void * data) +{ + assert (std::this_thread::get_id () == main_thread); + + // check that idle calls are run in the same order they were queued + assert (count == (int) (size_t) data); + + if (! (count % 10)) + printf ("UP: "); + + count ++; + + printf ("%d%c", count, (count % 10) ? ' ' : '\n'); +} + +static void count_down (void * data) +{ + assert (std::this_thread::get_id () == main_thread); + assert (data == & count); + + // check that the timer reports being started + assert (timer.running ()); + + count -= 10; + + printf ("DOWN: %d\n", count); + + if (! count) + { + // stop the timer + // queue up an idle call so it's pending at shutdown + // initiate the shutdown sequence + timer.queue (never_called, nullptr); + QueuedFunc::inhibit_all (); + mainloop_quit (); + } +} + +static void check_count (void * data) +{ + assert (std::this_thread::get_id () == main_thread); + + // check relative timing of 10 Hz timer and 250 ms delayed call + assert (count == (int) (size_t) data); + + printf ("CHECK: %d\n", count); +} + +static void worker () +{ + // queue some more idle calls from a secondary thread + for (int i = 50; i < 70; i ++) + counters[i].queue (count_up, (void *) (size_t) (i - 10)); + + // queue up a delayed call that should only be called once + delayed.queue (250, check_count, (void *) (size_t) 40); +} + +int main (int argc, const char * * argv) +{ + if (argc >= 2 && ! strcmp (argv[1], "--qt")) + use_qt = true; + + main_thread = std::this_thread::get_id (); + + // queue up a bunch of idle calls + for (int i = 0; i < 50; i ++) + counters[i].queue (count_up, (void *) (size_t) (i - 30)); + + // stop some of them + for (int i = 10; i < 30; i ++) + counters[i].stop (); + + // restart some that were stopped and some that weren't + for (int i = 0; i < 20; i ++) + counters[i].queue (count_up, (void *) (size_t) (20 + i)); + + // start a countdown timer at 10 Hz + timer.start (100, count_down, & count); + + // queue up a call and then immediately delete the QueuedFunc + QueuedFunc ().queue (never_called, nullptr); + + auto thread = std::thread (worker); + + mainloop_run (); + + thread.join (); + + // check that the timer reports being stopped + assert (! timer.running ()); + + return 0; +} diff --git a/src/libaudcore/tests/test.cc b/src/libaudcore/tests/test.cc new file mode 100644 index 0000000..d0ed8fe --- /dev/null +++ b/src/libaudcore/tests/test.cc @@ -0,0 +1,531 @@ +/* + * test.cc - Various tests for libaudcore + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "audio.h" +#include "audstrings.h" +#include "internal.h" +#include "ringbuf.h" +#include "tuple.h" +#include "tuple-compiler.h" +#include "vfs.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +static void test_audio_conversion () +{ + /* single precision float should be lossless for 24-bit audio */ + /* also test that high byte is correctly ignored/zeroed */ + static const int32_t in[10] = + {0x800000, 0x800001, 0x800002, -2, -1, 0, 1, 2, 0x7ffffe, 0x7fffff}; + + float f[10]; + char packed[30]; + int32_t out[10]; + + audio_from_int (in, FMT_S24_NE, f, 10); + + for (int format = FMT_S24_3LE; format <= FMT_U24_3BE; format ++) + { + memset (packed, 0, sizeof packed); + audio_to_int (f, packed, format, 10); + memset (f, 0, sizeof f); + audio_from_int (packed, format, f, 10); + } + + audio_to_int (f, out, FMT_S24_NE, 10); + + assert (f[0] == -1.0f); + assert (f[5] == 0.0f); + + for (int i = 0; i < 10; i ++) + assert (out[i] == (in[i] & 0xffffff)); +} + +static void test_case_conversion () +{ + const char in[] = "AÄaäEÊeêIÌiìOÕoõUÚuú"; + const char low_ascii[] = "aÄaäeÊeêiÌiìoÕoõuÚuú"; + const char low_utf8[] = "aäaäeêeêiìiìoõoõuúuú"; + const char hi_ascii[] = "AÄAäEÊEêIÌIìOÕOõUÚUú"; + const char hi_utf8[] = "AÄAÄEÊEÊIÌIÌOÕOÕUÚUÚ"; + + assert (! strcmp (low_ascii, str_tolower (in))); + assert (! strcmp (low_utf8, str_tolower_utf8 (in))); + assert (! strcmp (hi_ascii, str_toupper (in))); + assert (! strcmp (hi_utf8, str_toupper_utf8 (in))); + + assert (! strcmp_safe ("abc", "abc")); + assert (! strcmp_safe ("abc", "abcdef", 3)); + assert (strcmp_safe ("abc", "def") < 0); + assert (strcmp_safe ("def", "abc") > 0); + assert (! strcmp_safe (nullptr, nullptr)); + assert (strcmp_safe (nullptr, "abc") < 0); + assert (strcmp_safe ("abc", nullptr) > 0); + + assert (! strcmp_nocase ("abc", "ABC")); + assert (! strcmp_nocase ("ABC", "abcdef", 3)); + assert (strcmp_nocase ("abc", "DEF") < 0); + assert (strcmp_nocase ("ABC", "def") < 0); + assert (strcmp_nocase ("def", "ABC") > 0); + assert (strcmp_nocase ("DEF", "abc") > 0); + assert (! strcmp_nocase (nullptr, nullptr)); + assert (strcmp_nocase (nullptr, "abc") < 0); + assert (strcmp_nocase ("abc", nullptr) > 0); + + assert (! strcmp_nocase (in, low_ascii)); + assert (strcmp_nocase (in, low_utf8)); + assert (! strcmp_nocase (in, hi_ascii)); + assert (strcmp_nocase (in, hi_utf8)); + + assert (str_has_prefix_nocase (low_ascii, "AÄaä")); + assert (! str_has_prefix_nocase (low_utf8, "AÄaä")); + assert (str_has_prefix_nocase (hi_ascii, "AÄaä")); + assert (! str_has_prefix_nocase (hi_utf8, "AÄaä")); + + assert (str_has_suffix_nocase (low_ascii, "UÚuú")); + assert (! str_has_suffix_nocase (low_utf8, "UÚuú")); + assert (str_has_suffix_nocase (hi_ascii, "UÚuú")); + assert (! str_has_suffix_nocase (hi_utf8, "UÚuú")); + + assert (! str_has_suffix_nocase ("abc", "abcd")); + + assert (! strcmp (strstr_nocase (low_ascii, "OÕoõ"), "oÕoõuÚuú")); + assert (strstr_nocase (low_utf8, "OÕoõ") == nullptr); + assert (! strcmp (strstr_nocase (hi_ascii, "OÕoõ"), "OÕOõUÚUú")); + assert (strstr_nocase (hi_utf8, "OÕoõ") == nullptr); + + assert (! strcmp (strstr_nocase_utf8 (low_ascii, "OÕoõ"), "oÕoõuÚuú")); + assert (! strcmp (strstr_nocase_utf8 (low_utf8, "OÕoõ"), "oõoõuúuú")); + assert (strstr_nocase_utf8 (low_utf8, "OOoo") == nullptr); + assert (! strcmp (strstr_nocase_utf8 (hi_ascii, "OÕoõ"), "OÕOõUÚUú")); + assert (! strcmp (strstr_nocase_utf8 (hi_utf8, "OÕoõ"), "OÕOÕUÚUÚ")); + assert (strstr_nocase_utf8 (hi_utf8, "OOoo") == nullptr); +} + +static void test_numeric_conversion () +{ + static const char * in[] = { + "", + "x1234", + "+2147483647", + "-2147483648", + "999999999.999999", + "999999999.9999996", + "000000000000000000000000100000.000001000000000000000000000000", + "--5", + "3.+5", + "-6.7 dB" + }; + + static const char * out_double[] = { + "0", + "0", + "2147483647", + "-2147483648", + "999999999.999999", + "1000000000", + "100000.000001", + "0", + "3", + "-6.7" + }; + + static const char * out_int[] = { + "0", + "0", + "2147483647", + "-2147483648", + "999999999", + "999999999", + "100000", + "0", + "3", + "-6" + }; + + for (int i = 0; i < aud::n_elems (in); i ++) + { + double d_val = str_to_double (in[i]); + int i_val = str_to_int (in[i]); + StringBuf via_double = double_to_str (d_val); + StringBuf via_int = int_to_str (i_val); + + if (strcmp (via_double, out_double[i]) || strcmp (via_int, out_int[i])) + { + printf ("Converting [%s]\n", in[i]); + printf ("Expected [%s] and [%s]\n", out_double[i], out_int[i]); + printf ("Via [%g] and [%d]\n", d_val, i_val); + printf ("Got [%s] and [%s]\n", (const char *) via_double, (const char *) via_int); + exit (1); + } + } +} + +static void test_filename_split () +{ + /* expected results differ slightly from POSIX dirname/basename */ + static const char * const paths[][3] = { + {"/usr/lib/aud", "/usr/lib", "aud"}, + {"/usr/lib/", "/usr", "lib"}, + {"/usr/lib", "/usr", "lib"}, + {"/usr/", "/", "usr"}, + {"/usr", "/", "usr"}, + {"/", nullptr, "/"} + }; + + for (int i = 0; i < aud::n_elems (paths); i ++) + { + assert (! strcmp_safe (filename_get_parent (paths[i][0]), paths[i][1])); + assert (! strcmp_safe (filename_get_base (paths[i][0]), paths[i][2])); + } +} + +static void test_tuple_format (const char * format, Tuple & tuple, const char * expected) +{ + TupleCompiler compiler; + compiler.compile (format); + compiler.format (tuple); + + String result = tuple.get_str (Tuple::FormattedTitle); + if (strcmp (result, expected)) + { + printf ("For format [%s]\n", format); + printf ("Expected [%s]\n", expected); + printf ("Got [%s]\n", (const char *) result); + exit (1); + } +} + +static void test_tuple_formats () +{ + Tuple tuple; + + /* fallback tests */ + test_tuple_format ("", tuple, ""); + tuple.set_filename ("http://Path%20To/File%20Name"); + test_tuple_format ("", tuple, "File Name"); + tuple.set_str (Tuple::Title, "Song Title"); + test_tuple_format ("", tuple, "Song Title"); + + /* basic variable tests */ + test_tuple_format ("$", tuple, "Song Title"); + test_tuple_format ("${", tuple, "Song Title"); + test_tuple_format ("${file-name", tuple, "Song Title"); + test_tuple_format ("${file-name}", tuple, "File Name"); + test_tuple_format ("${file-name}}", tuple, "Song Title"); + test_tuple_format ("${invalid}", tuple, "Song Title"); + test_tuple_format ("${}", tuple, "Song Title"); + test_tuple_format ("\\$\\{\\}", tuple, "${}"); + test_tuple_format ("\\\0" "a", tuple, "Song Title"); + test_tuple_format ("{}", tuple, "Song Title"); + + /* integer variable tests */ + test_tuple_format ("${year}", tuple, "Song Title"); + tuple.set_int (Tuple::Year, -1); + test_tuple_format ("${year}", tuple, "-1"); + tuple.set_int (Tuple::Year, 0); + test_tuple_format ("${year}", tuple, "0"); + tuple.set_int (Tuple::Year, 1990); + test_tuple_format ("${year}", tuple, "1990"); + + /* filename variable tests */ + test_tuple_format ("${file-path}", tuple, "http://Path To/"); + test_tuple_format ("${file-ext}", tuple, "Song Title"); + tuple.set_filename ("http://Path%20To/File%20Name.Ext?3"); + test_tuple_format ("${file-name}", tuple, "File Name"); + test_tuple_format ("${file-ext}", tuple, "Ext"); + test_tuple_format ("${subsong-id}", tuple, "3"); + + /* existence tests */ + test_tuple_format ("x${?invalid:Field Exists}", tuple, "Song Title"); + test_tuple_format ("x${?subsong-id:Field Exists", tuple, "Song Title"); + test_tuple_format ("x${?subsong-id:Field Exists}", tuple, "xField Exists"); + test_tuple_format ("x${?subsong-id:${invalid}}", tuple, "Song Title"); + test_tuple_format ("x${?subsong-id:(${subsong-id})}", tuple, "x(3)"); + test_tuple_format ("x${?track-number:Field Exists}", tuple, "x"); + test_tuple_format ("x${?title:Field Exists}", tuple, "xField Exists"); + test_tuple_format ("x${?artist:Field Exists}", tuple, "x"); + test_tuple_format ("x${?artist}", tuple, "Song Title"); + + /* equality tests */ + test_tuple_format ("x${=}", tuple, "Song Title"); + test_tuple_format ("x${==}", tuple, "Song Title"); + test_tuple_format ("x${==a,}", tuple, "Song Title"); + test_tuple_format ("x${==a,a:}", tuple, "Song Title"); + test_tuple_format ("x${==\"a\",a:}", tuple, "Song Title"); + test_tuple_format ("x${==\"a\",\"a:Equal}", tuple, "Song Title"); + test_tuple_format ("x${==\"a\",\"a\":Equal}", tuple, "xEqual"); + test_tuple_format ("x${==\"a\",\"a\"\":Equal}", tuple, "Song Title"); + test_tuple_format ("x${==\"a\",\"b\":Equal}", tuple, "x"); + test_tuple_format ("x${==year,\"a\":Equal}", tuple, "x"); + test_tuple_format ("x${==\"a\",year:Equal}", tuple, "x"); + test_tuple_format ("x${==year,1990:Equal}", tuple, "xEqual"); + test_tuple_format ("x${==1990,year:Equal}", tuple, "xEqual"); + test_tuple_format ("x${==title,\"a\":Equal}", tuple, "x"); + test_tuple_format ("x${==\"a\",title:Equal}", tuple, "x"); + test_tuple_format ("x${==title,\"Song Title\":Equal}", tuple, "xEqual"); + test_tuple_format ("x${==\"Song Title\",title:Equal}", tuple, "xEqual"); + tuple.set_str (Tuple::Artist, "{}"); + test_tuple_format ("x${==artist,\"\\{\\}\":Equal}", tuple, "xEqual"); + + /* inequality tests */ + test_tuple_format ("x${!}", tuple, "Song Title"); + test_tuple_format ("x${!=}", tuple, "Song Title"); + test_tuple_format ("x${!=\"a\",\"a\":Unequal}", tuple, "x"); + test_tuple_format ("x${!=\"a\",\"b\":Unequal}", tuple, "xUnequal"); + test_tuple_format ("x${!=year,\"a\":Unequal}", tuple, "xUnequal"); + test_tuple_format ("x${!=\"a\",year:Unequal}", tuple, "xUnequal"); + test_tuple_format ("x${!=year,1990:Unequal}", tuple, "x"); + test_tuple_format ("x${!=1990,year:Unequal}", tuple, "x"); + test_tuple_format ("x${>}", tuple, "Song Title"); + test_tuple_format ("x${>year,1989:Greater}", tuple, "xGreater"); + test_tuple_format ("x${>year,1990:Greater}", tuple, "x"); + test_tuple_format ("x${>=year,1990:NotLess}", tuple, "xNotLess"); + test_tuple_format ("x${>=year,1991:NotLess}", tuple, "x"); + test_tuple_format ("x${<}", tuple, "Song Title"); + test_tuple_format ("x${<year,1991:Less}", tuple, "xLess"); + test_tuple_format ("x${<year,1990:Less}", tuple, "x"); + test_tuple_format ("x${<=year,1990:NotGreater}", tuple, "xNotGreater"); + test_tuple_format ("x${<=year,1989:NotGreater}", tuple, "x"); + + /* emptiness tests */ + tuple.set_int (Tuple::Year, 0); + tuple.set_str (Tuple::Artist, ""); + test_tuple_format ("x${(invalid)}", tuple, "Song Title"); + test_tuple_format ("x${(empty)?invalid:Empty}", tuple, "Song Title"); + test_tuple_format ("x${(empty)?subsong-id:Empty}", tuple, "x"); + test_tuple_format ("x${(empty)?subsong-id:${invalid}}", tuple, "Song Title"); + test_tuple_format ("x${(empty)?year:Empty}", tuple, "x"); + test_tuple_format ("x${(empty)?track-number:Empty}", tuple, "xEmpty"); + test_tuple_format ("x${(empty)?title:Empty}", tuple, "x"); + test_tuple_format ("x${(empty)?artist:Empty}", tuple, "x"); + test_tuple_format ("x${(empty)?album:Empty}", tuple, "xEmpty"); + test_tuple_format ("x${(empty)?\"Literal\":Empty}", tuple, "Song Title"); +} + +static void test_ringbuf () +{ + String nums[10]; + for (int i = 0; i < 10; i ++) + nums[i] = String (int_to_str (i)); + + RingBuf<String> ring; + + ring.alloc (7); + + for (int i = 0; i < 7; i ++) + assert (ring.push (nums[i]) == nums[i]); + + for (int i = 0; i < 5; i ++) + { + assert (ring.head () == nums[i]); + ring.pop (); + } + + for (int i = 7; i < 10; i ++) + assert (ring.push (nums[i]) == nums[i]); + + assert (ring.size () == 7); + assert (ring.len () == 5); + assert (ring.linear () == 2); + assert (ring.space () == 2); + + ring.alloc (5); + + for (int i = 0; i < 5; i ++) + assert (ring[i] == nums[5 + i]); + + assert (ring.size () == 5); + assert (ring.len () == 5); + assert (ring.linear () == 2); + assert (ring.space () == 0); + + ring.alloc (10); + + for (int i = 0; i < 5; i ++) + assert (ring[i] == nums[5 + i]); + + assert (ring.size () == 10); + assert (ring.len () == 5); + assert (ring.linear () == 2); + assert (ring.space () == 5); + + for (int i = 0; i < 5; i ++) + assert (ring[i] == nums[5 + i]); + + for (int i = 5; i --; ) + assert (ring.push (nums[i]) == nums[i]); + + for (int i = 0; i < 5; i ++) + { + assert (ring.head () == nums[5 + i]); + ring.pop (); + } + + for (int i = 0; i < 5; i ++) + { + assert (ring.head () == nums[4 - i]); + ring.pop (); + } + + ring.copy_in (& nums[5], 5); + ring.copy_in (& nums[0], 5); + + for (int i = 0; i < 5; i ++) + { + assert (ring.head () == nums[5 + i]); + ring.pop (); + } + + for (int i = 0; i < 5; i ++) + { + assert (ring.head () == nums[i]); + ring.pop (); + } + + ring.move_in (nums, 10); + + for (int i = 0; i < 10; i ++) + { + assert (! nums[i]); + assert (ring[i] == String (int_to_str (i))); + } + + ring.move_out (& nums[5], 5); + ring.move_out (& nums[0], 5); + + for (int i = 0; i < 10; i ++) + assert (nums[i] == String (int_to_str ((5 + i) % 10))); + + ring.move_in (nums, 10); + + Index<String> index; + ring.move_out (index, -1, 5); + + assert (ring.len () == 5); + assert (index.len () == 5); + + ring.move_out (index, 0, -1); + + assert (ring.len () == 0); + assert (index.len () == 10); + + for (int i = 0; i < 10; i ++) + assert (index[i] == String (int_to_str (i))); + + ring.move_in (index, 5, 5); + + assert (ring.len () == 5); + assert (index.len () == 5); + + ring.move_in (index, 0, -1); + + assert (ring.len () == 10); + assert (index.len () == 0); + + for (int i = 0; i < 10; i ++) + assert (ring[i] == String (int_to_str ((5 + i) % 10))); + + ring.discard (5); + assert (ring.len () == 5); + + ring.discard (); + assert (ring.len () == 0); + + string_leak_check (); +} + +static StringBuf str_recursive_insert (const char * str, int level) +{ + StringBuf buf = str_copy (str); + buf.insert (buf.len () / 2, str); + + if (level == 1) + return buf; + + // intentionally causing fragmentation here + return str_recursive_insert (buf, level - 1); +} + +static StringBuf str_repeated_nest (const char * str, int level) +{ + StringBuf buf1 = str_copy (str); + StringBuf buf2 = str_copy (str); + + while (level -- > 0) + { + buf1.insert (buf1.len () / 2, buf2); + buf2.insert (buf2.len () / 2, buf1); + } + + // intentionally causing fragmentation here + return buf2; +} + +static void test_stringbuf () +{ + char expect[262145]; + + StringBuf str1 = str_recursive_insert ("ab", 17).settle (); + + memset (expect, 'a', 121393); + memset (expect + 121393, 'b', 121393); + expect[242786] = 0; + + assert (! strcmp (str_repeated_nest ("ab", 12), expect)); + + memset (expect, 'a', 131072); + memset (expect + 131072, 'b', 131072); + expect[262144] = 0; + + assert (! strcmp (str1, expect)); +} + +static void test_str_printf () +{ + StringBuf problem = str_printf ("%d", 6); + const char * loc1 = problem; + str_append_printf (problem, " * %d", 7); + const char * loc2 = problem; + + assert (loc1 == loc2); + assert (! strcmp (problem, "6 * 7")); + + StringBuf answer = str_printf ("%d", 6 * 7); + str_append_printf (problem, " = %s", (const char *) answer); + + assert (! strcmp (problem, "6 * 7 = 42")); +} + +int main () +{ + test_audio_conversion (); + test_case_conversion (); + test_numeric_conversion (); + test_filename_split (); + test_tuple_formats (); + test_ringbuf (); + test_stringbuf (); + test_str_printf (); + + return 0; +} diff --git a/src/libaudcore/threads.h b/src/libaudcore/threads.h new file mode 100644 index 0000000..2f13b0c --- /dev/null +++ b/src/libaudcore/threads.h @@ -0,0 +1,100 @@ +/* + * threads.h + * Copyright 2019 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_THREADS_H +#define LIBAUDCORE_THREADS_H + +#include <libaudcore/templates.h> +#include <libaudcore/tinylock.h> + +#include <condition_variable> +#include <mutex> +#include <thread> + +namespace aud +{ + +/* A wrapper class around TinyLock, encouraging correct usage */ +class spinlock +{ +public: + spinlock() = default; + + /* Not copyable or movable */ + spinlock(const spinlock &) = delete; + spinlock & operator=(const spinlock &) = delete; + + /* Explicit lock/unlock */ + void lock() { tiny_lock(&m_lock); } + void unlock() { tiny_unlock(&m_lock); } + + /* Scope-based lock ownership */ + typedef owner<spinlock, &spinlock::lock, &spinlock::unlock> holder; + /* Convenience method for taking ownership of the lock */ + holder take() __attribute__((warn_unused_result)) { return holder(this); } + +private: + TinyLock m_lock = 0; +}; + +/* A wrapper class around TinyRWLock, encouraging correct usage */ +class spinlock_rw +{ +public: + spinlock_rw() = default; + + /* Not copyable or movable */ + spinlock_rw(const spinlock_rw &) = delete; + spinlock_rw & operator=(const spinlock_rw &) = delete; + + /* Explicit lock/unlock */ + void lock_r() { tiny_lock_read(&m_lock); } + void unlock_r() { tiny_unlock_read(&m_lock); } + void lock_w() { tiny_lock_write(&m_lock); } + void unlock_w() { tiny_unlock_write(&m_lock); } + + /* Scope-based lock ownership */ + typedef owner<spinlock_rw, &spinlock_rw::lock_r, &spinlock_rw::unlock_r> + reader; + typedef owner<spinlock_rw, &spinlock_rw::lock_w, &spinlock_rw::unlock_w> + writer; + /* Convenience methods for taking ownership of the lock */ + reader read() __attribute__((warn_unused_result)) { return reader(this); } + writer write() __attribute__((warn_unused_result)) { return writer(this); } + +private: + TinyRWLock m_lock = 0; +}; + +/* An alias for std::mutex */ +class mutex : public std::mutex +{ +public: + /* Scope-based lock ownership */ + typedef std::unique_lock<std::mutex> holder; + /* Convenience method for taking ownership of the lock */ + holder take() __attribute__((warn_unused_result)) { return holder(*this); } +}; + +/* An alias for std::condition_variable */ +typedef std::condition_variable condvar; + +} // namespace aud + +#endif // LIBAUDCORE_THREADS_H diff --git a/src/libaudcore/timer.cc b/src/libaudcore/timer.cc new file mode 100644 index 0000000..2443f04 --- /dev/null +++ b/src/libaudcore/timer.cc @@ -0,0 +1,132 @@ +/* + * timer.c + * Copyright 2015 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "hook.h" +#include "index.h" +#include "internal.h" +#include "mainloop.h" +#include "runtime.h" +#include "threads.h" + +static const aud::array<TimerRate, int> rate_to_ms = {1000, 250, 100, 33}; + +struct TimerItem +{ + TimerFunc func; + void * data; +}; + +struct TimerList +{ + QueuedFunc source; + Index<TimerItem> items; + int use_count = 0; + + bool contains(TimerFunc func, void * data) const + { + for (auto & item : items) + { + if (item.func == func && item.data == data) + return true; + } + + return false; + } + + void check_stop() + { + if (!use_count) + { + auto is_empty = [](const TimerItem & item) { return !item.func; }; + + items.remove_if(is_empty, true); + + if (!items.len() && source.running()) + source.stop(); + } + } +}; + +static aud::mutex mutex; +static aud::array<TimerRate, TimerList> lists; + +static void timer_run(void * list_) +{ + auto & list = *(TimerList *)list_; + auto mh = mutex.take(); + + list.use_count++; + + /* note: the list may grow (but not shrink) during the call */ + for (int i = 0; i < list.items.len(); i++) + { + /* copy locally to prevent race condition */ + TimerItem item = list.items[i]; + + if (item.func) + { + mh.unlock(); + item.func(item.data); + mh.lock(); + } + } + + list.use_count--; + list.check_stop(); +} + +EXPORT void timer_add(TimerRate rate, TimerFunc func, void * data) +{ + auto & list = lists[rate]; + auto mh = mutex.take(); + + if (!list.contains(func, data)) + { + list.items.append(func, data); + + if (!list.source.running()) + list.source.start(rate_to_ms[rate], timer_run, &list); + } +} + +EXPORT void timer_remove(TimerRate rate, TimerFunc func, void * data) +{ + auto & list = lists[rate]; + auto mh = mutex.take(); + + for (TimerItem & item : list.items) + { + if (item.func == func && (!data || item.data == data)) + item.func = nullptr; + } + + list.check_stop(); +} + +void timer_cleanup() +{ + auto mh = mutex.take(); + + int timers_running = 0; + for (TimerList & list : lists) + timers_running += list.items.len(); + + if (timers_running) + AUDWARN("%d timers still registered at exit\n", timers_running); +} diff --git a/src/libaudcore/tinylock.cc b/src/libaudcore/tinylock.cc new file mode 100644 index 0000000..0424e8b --- /dev/null +++ b/src/libaudcore/tinylock.cc @@ -0,0 +1,59 @@ +/* + * tinylock.c + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "tinylock.h" + +#include <limits.h> +#include <sched.h> + +#define WRITE_BIT (SHRT_MAX + 1) + +EXPORT void tiny_lock(TinyLock * lock) +{ + while (__builtin_expect(__sync_lock_test_and_set(lock, 1), 0)) + sched_yield(); +} + +EXPORT void tiny_unlock(TinyLock * lock) { __sync_lock_release(lock); } + +EXPORT void tiny_lock_read(TinyRWLock * lock) +{ + while (__builtin_expect(__sync_fetch_and_add(lock, 1) & WRITE_BIT, 0)) + { + __sync_fetch_and_sub(lock, 1); + sched_yield(); + } +} + +EXPORT void tiny_unlock_read(TinyRWLock * lock) +{ + __sync_fetch_and_sub(lock, 1); +} + +EXPORT void tiny_lock_write(TinyRWLock * lock) +{ + while ( + !__builtin_expect(__sync_bool_compare_and_swap(lock, 0, WRITE_BIT), 1)) + sched_yield(); +} + +EXPORT void tiny_unlock_write(TinyRWLock * lock) +{ + __sync_fetch_and_sub(lock, WRITE_BIT); +} diff --git a/src/libaudcore/tinylock.h b/src/libaudcore/tinylock.h new file mode 100644 index 0000000..1b16a06 --- /dev/null +++ b/src/libaudcore/tinylock.h @@ -0,0 +1,43 @@ +/* + * tinylock.h + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_TINYLOCK_H +#define LIBAUDCORE_TINYLOCK_H + +/* + * TinyLock is an extremely low-overhead lock object (in terms of speed and + * memory usage). It makes no guarantees of fair scheduling, however. + * + * Consider using the aud::spinlock wrapper class from threads.h rather than + * using this API directly. + */ + +typedef char TinyLock; + +void tiny_lock(TinyLock * lock); +void tiny_unlock(TinyLock * lock); + +typedef unsigned short TinyRWLock; + +void tiny_lock_read(TinyRWLock * lock); +void tiny_unlock_read(TinyRWLock * lock); +void tiny_lock_write(TinyRWLock * lock); +void tiny_unlock_write(TinyRWLock * lock); + +#endif /* LIBAUDCORE_TINYLOCK_H */ diff --git a/src/libaudcore/tuple-compiler.cc b/src/libaudcore/tuple-compiler.cc new file mode 100644 index 0000000..97198b5 --- /dev/null +++ b/src/libaudcore/tuple-compiler.cc @@ -0,0 +1,556 @@ +/* + * tuple_compiler.c + * Copyright (c) 2007 Matti 'ccr' Hämäläinen + * Copyright (c) 2011-2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stdlib.h> +#include <string.h> + +#include <glib.h> +#include <new> + +#include "audstrings.h" +#include "runtime.h" +#include "tuple-compiler.h" + +struct Variable +{ + enum + { + Invalid = 0, + Text, + Integer, + Field + } type; + + String text; + int integer; + Tuple::Field field; + + bool set(const char * name, bool literal); + bool exists(const Tuple & tuple) const; + Tuple::ValueType get(const Tuple & tuple, String & tmps, int & tmpi) const; +}; + +enum class Op +{ + Invalid = 0, + Var, + Exists, + Equal, + Unequal, + Greater, + GreaterEqual, + Less, + LessEqual, + Empty +}; + +struct TupleCompiler::Node +{ + Op op; + Variable var1, var2; + Index<Node> children; +}; + +typedef TupleCompiler::Node Node; + +bool Variable::set(const char * name, bool literal) +{ + if (g_ascii_isdigit(name[0])) + { + type = Integer; + integer = atoi(name); + } + else if (literal) + { + type = Text; + text = String(name); + } + else + { + type = Field; + field = Tuple::field_by_name(name); + + if (field < 0) + { + AUDWARN("Invalid variable '%s'.\n", name); + return false; + } + } + + return true; +} + +bool Variable::exists(const Tuple & tuple) const +{ + g_return_val_if_fail(type == Field, false); + return tuple.get_value_type(field) != Tuple::Empty; +} + +Tuple::ValueType Variable::get(const Tuple & tuple, String & tmps, + int & tmpi) const +{ + switch (type) + { + case Text: + tmps = text; + return Tuple::String; + + case Integer: + tmpi = integer; + return Tuple::Int; + + case Field: + switch (tuple.get_value_type(field)) + { + case Tuple::String: + tmps = tuple.get_str(field); + return Tuple::String; + + case Tuple::Int: + tmpi = tuple.get_int(field); + return Tuple::Int; + + default: + return Tuple::Empty; + } + + default: + g_return_val_if_reached(Tuple::Empty); + } +} + +TupleCompiler::TupleCompiler() {} +TupleCompiler::~TupleCompiler() {} + +static StringBuf get_item(const char *& str, char endch, bool & literal) +{ + const char * s = str; + + StringBuf buf(-1); + char * set = buf; + char * stop = buf + buf.len(); + + if (*s == '"') + { + if (!literal) + { + buf = StringBuf(); // release space before AUDWARN + AUDWARN("Unexpected string literal at '%s'.\n", s); + return StringBuf(); + } + + s++; + } + else + literal = false; + + if (literal) + { + while (*s != '"') + { + if (*s == '\\') + s++; + + if (!*s) + { + buf = StringBuf(); // release space before AUDWARN + AUDWARN("Unterminated string literal.\n"); + return StringBuf(); + } + + if (set == stop) + throw std::bad_alloc(); + + *set++ = *s++; + } + + s++; + } + else + { + while (g_ascii_isalnum(*s) || *s == '-') + { + if (set == stop) + throw std::bad_alloc(); + + *set++ = *s++; + } + } + + if (*s != endch) + { + buf = StringBuf(); // release space before AUDWARN + AUDWARN("Expected '%c' at '%s'.\n", endch, s); + return StringBuf(); + } + + str = s + 1; + + buf.resize(set - buf); + return buf; +} + +static bool compile_expression(Index<Node> & nodes, const char *& expression); + +static bool parse_construct(Node & node, const char *& c) +{ + bool literal1 = true, literal2 = true; + + StringBuf tmps1 = get_item(c, ',', literal1); + if (!tmps1) + return false; + + StringBuf tmps2 = get_item(c, ':', literal2); + if (!tmps2) + return false; + + if (!node.var1.set(tmps1, literal1)) + return false; + + if (!node.var2.set(tmps2, literal2)) + return false; + + return compile_expression(node.children, c); +} + +/* Compile format expression into Node tree. */ +static bool compile_expression(Index<Node> & nodes, const char *& expression) +{ + const char * c = expression; + + while (*c && *c != '}') + { + Node & node = nodes.append(); + + if (*c == '$') + { + /* Expression? */ + if (c[1] != '{') + { + AUDWARN("Expected '${' at '%s'.\n", c); + return false; + } + + c += 2; + + switch (*c) + { + case '?': + case '(': + { + if (*c == '?') + { + node.op = Op::Exists; + c++; + } + else + { + if (strncmp(c, "(empty)?", 8)) + { + AUDWARN("Expected '(empty)?' at '%s'.\n", c); + return false; + } + + node.op = Op::Empty; + c += 8; + } + + bool literal = false; + StringBuf tmps = get_item(c, ':', literal); + if (!tmps) + return false; + + if (!node.var1.set(tmps, false)) + return false; + + if (!compile_expression(node.children, c)) + return false; + + break; + } + + case '=': + case '!': + node.op = (*c == '=') ? Op::Equal : Op::Unequal; + + if (c[1] != '=') + { + AUDWARN("Expected '%c=' at '%s'.\n", c[0], c); + return false; + } + + c += 2; + + if (!parse_construct(node, c)) + return false; + + break; + + case '<': + case '>': + if (c[1] == '=') + { + node.op = (*c == '<') ? Op::LessEqual : Op::GreaterEqual; + c += 2; + } + else + { + node.op = (*c == '<') ? Op::Less : Op::Greater; + c++; + } + + if (!parse_construct(node, c)) + return false; + + break; + + default: + { + bool literal = false; + StringBuf tmps = get_item(c, '}', literal); + if (!tmps) + return false; + + c--; + + node.op = Op::Var; + + if (!node.var1.set(tmps, false)) + return false; + } + } + + if (*c != '}') + { + AUDWARN("Expected '}' at '%s'.\n", c); + return false; + } + + c++; + } + else if (*c == '{') + { + AUDWARN("Unexpected '%c' at '%s'.\n", *c, c); + return false; + } + else + { + /* Parse raw/literal text */ + StringBuf buf(-1); + char * set = buf; + char * stop = buf + buf.len(); + + while (*c && *c != '$' && *c != '{' && *c != '}') + { + if (*c == '\\') + { + c++; + + if (!*c) + { + buf = StringBuf(); // release space before AUDWARN + AUDWARN("Incomplete escaped character.\n"); + return false; + } + } + + if (set == stop) + throw std::bad_alloc(); + + *set++ = *c++; + } + + buf.resize(set - buf); + + node.op = Op::Var; + node.var1.type = Variable::Text; + node.var1.text = String(buf); + } + } + + expression = c; + return true; +} + +bool TupleCompiler::compile(const char * expr) +{ + const char * c = expr; + Index<Node> nodes; + + if (!compile_expression(nodes, c)) + return false; + + if (*c) + { + AUDWARN("Unexpected '%c' at '%s'.\n", *c, c); + return false; + } + + root_nodes = std::move(nodes); + return true; +} + +void TupleCompiler::reset() { root_nodes.clear(); } + +/* Evaluate tuple in given TupleEval expression in given + * context and return resulting string. */ +static void eval_expression(const Index<Node> & nodes, const Tuple & tuple, + StringBuf & out) +{ + for (const Node & node : nodes) + { + switch (node.op) + { + case Op::Var: + { + String tmps; + int tmpi; + + switch (node.var1.get(tuple, tmps, tmpi)) + { + case Tuple::String: + out.insert(-1, tmps); + break; + + case Tuple::Int: + str_insert_int(out, -1, tmpi); + break; + + default: + break; + } + + break; + } + + case Op::Equal: + case Op::Unequal: + case Op::Less: + case Op::LessEqual: + case Op::Greater: + case Op::GreaterEqual: + { + bool result = false; + String tmps1, tmps2; + int tmpi1 = 0, tmpi2 = 0; + + Tuple::ValueType type1 = node.var1.get(tuple, tmps1, tmpi1); + Tuple::ValueType type2 = node.var2.get(tuple, tmps2, tmpi2); + + if (type1 != Tuple::Empty && type2 != Tuple::Empty) + { + int resulti; + + if (type1 == type2) + { + if (type1 == Tuple::String) + resulti = strcmp(tmps1, tmps2); + else + resulti = tmpi1 - tmpi2; + } + else + { + if (type1 == Tuple::Int) + resulti = tmpi1 - atoi(tmps2); + else + resulti = atoi(tmps1) - tmpi2; + } + + switch (node.op) + { + case Op::Equal: + result = (resulti == 0); + break; + + case Op::Unequal: + result = (resulti != 0); + break; + + case Op::Less: + result = (resulti < 0); + break; + + case Op::LessEqual: + result = (resulti <= 0); + break; + + case Op::Greater: + result = (resulti > 0); + break; + + case Op::GreaterEqual: + result = (resulti >= 0); + break; + + default: + g_warn_if_reached(); + } + } + + if (result) + eval_expression(node.children, tuple, out); + + break; + } + + case Op::Exists: + if (node.var1.exists(tuple)) + eval_expression(node.children, tuple, out); + + break; + + case Op::Empty: + if (!node.var1.exists(tuple)) + eval_expression(node.children, tuple, out); + + break; + + default: + g_warn_if_reached(); + } + } +} + +void TupleCompiler::format(Tuple & tuple) const +{ + tuple.unset(Tuple::FormattedTitle); // prevent recursion + + StringBuf buf(0); + eval_expression(root_nodes, tuple, buf); + + if (buf[0]) + { + tuple.set_str(Tuple::FormattedTitle, buf); + return; + } + + /* formatting failed, try fallbacks */ + for (Tuple::Field fallback : {Tuple::Title, Tuple::Basename}) + { + String title = tuple.get_str(fallback); + if (title) + { + tuple.set_str(Tuple::FormattedTitle, title); + return; + } + } + + tuple.set_str(Tuple::FormattedTitle, ""); +} diff --git a/src/libaudcore/tuple-compiler.h b/src/libaudcore/tuple-compiler.h new file mode 100644 index 0000000..3e25faf --- /dev/null +++ b/src/libaudcore/tuple-compiler.h @@ -0,0 +1,63 @@ +/* + * tuple_compiler.h + * Copyright (c) 2007 Matti 'ccr' Hämäläinen + * Copyright (c) 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +/* + * the tuple formatter: + * + * this is a data-driven meta-language. + * + * language constructs follow the following basic rules: + * - begin with ${ + * - end with } + * + * language constructs: + * - ${field}: prints a field + * - ${?field:expr}: evaluates expr if field exists + * - ${==field,field:expr}: evaluates expr if both fields are the same + * - ${!=field,field:expr}: evaluates expr if both fields are not the same + * - ${(empty)?field:expr}: evaluates expr if field does not exist + * + * everything else is treated as raw text. + */ + +#ifndef LIBAUDCORE_TUPLE_COMPILER_H +#define LIBAUDCORE_TUPLE_COMPILER_H + +#include <libaudcore/index.h> +#include <libaudcore/tuple.h> + +class TupleCompiler +{ +public: + struct Node; + + TupleCompiler(); + ~TupleCompiler(); + + bool compile(const char * expr); + void reset(); + + void format(Tuple & tuple) const; + +private: + Index<Node> root_nodes; +}; + +#endif /* LIBAUDCORE_TUPLE_COMPILER_H */ diff --git a/src/libaudcore/tuple.cc b/src/libaudcore/tuple.cc new file mode 100644 index 0000000..7d710b4 --- /dev/null +++ b/src/libaudcore/tuple.cc @@ -0,0 +1,881 @@ +/* + * tuple.c + * Copyright 2007-2013 Ariadne Conill, Christian Birchinger, Matti Hämäläinen, + * Giacomo Lozito, Eugene Zagidullin, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <assert.h> +#include <math.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <glib.h> /* for g_utf8_validate */ + +#include "audio.h" +#include "audstrings.h" +#include "i18n.h" +#include "tuple.h" +#include "vfs.h" + +enum +{ + FallbackTitle = Tuple::n_fields, + FallbackArtist, + FallbackAlbum, + + n_private_fields +}; + +static_assert(n_private_fields <= 64, + "The current tuple implementation is limited to 64 fields"); + +union TupleVal { + String str; + int x; + + // dummy constructor and destructor + TupleVal() {} + ~TupleVal() {} +}; + +/** + * Structure for holding and passing around miscellaneous track + * metadata. This is not the same as a playlist entry, though. + */ +struct TupleData +{ + uint64_t setmask; // which fields are present + Index<TupleVal> vals; // ordered list of field values + + short * subtunes; /**< Array of int containing subtune index numbers. + Can be nullptr if indexing is linear or if + there are no subtunes. */ + short nsubtunes; /**< Number of subtunes, if any. Values greater than 0 + mean that there are subtunes and #subtunes array + may be set. */ + + short state; + int refcount; + + TupleData(); + ~TupleData(); + + TupleData(const TupleData & other); + void operator=(const TupleData & other) = delete; + + bool is_set(int field) const { return (setmask & bitmask(field)); } + + bool is_same(const TupleData & other) const; + + TupleVal * lookup(int field, bool add, bool remove); + void set_int(int field, int x); + void set_str(int field, const char * str); + void set_subtunes(short nsubs, const short * subs); + + static TupleData * ref(TupleData * tuple); + static void unref(TupleData * tuple); + + static TupleData * copy_on_write(TupleData * tuple); + +private: + static constexpr uint64_t bitmask(int n) { return (uint64_t)1 << n; } +}; + +/** Ordered table of basic #Tuple field names and their #ValueType. + */ +static const struct +{ + const char * name; + Tuple::ValueType type; + int fallback; +} field_info[] = { + {"title", Tuple::String, FallbackTitle}, + {"artist", Tuple::String, FallbackArtist}, + {"album", Tuple::String, FallbackAlbum}, + {"album-artist", Tuple::String, -1}, + {"comment", Tuple::String, -1}, + {"genre", Tuple::String, -1}, + {"year", Tuple::Int, -1}, + + {"composer", Tuple::String, -1}, + {"performer", Tuple::String, -1}, + {"copyright", Tuple::String, -1}, + {"date", Tuple::String, -1}, + + {"track-number", Tuple::Int, -1}, + {"length", Tuple::Int, -1}, + + {"bitrate", Tuple::Int, -1}, + {"codec", Tuple::String, -1}, + {"quality", Tuple::String, -1}, + + {"file-name", Tuple::String, -1}, + {"file-path", Tuple::String, -1}, + {"file-ext", Tuple::String, -1}, + + {"audio-file", Tuple::String, -1}, + + {"subsong-id", Tuple::Int, -1}, + {"subsong-num", Tuple::Int, -1}, + + {"segment-start", Tuple::Int, -1}, + {"segment-end", Tuple::Int, -1}, + + {"gain-album-gain", Tuple::Int, -1}, + {"gain-album-peak", Tuple::Int, -1}, + {"gain-track-gain", Tuple::Int, -1}, + {"gain-track-peak", Tuple::Int, -1}, + {"gain-gain-unit", Tuple::Int, -1}, + {"gain-peak-unit", Tuple::Int, -1}, + + {"formatted-title", Tuple::String, -1}, + + {"description", Tuple::String, -1}, + {"musicbrainz-id", Tuple::String, -1}, + + /* fallbacks */ + {nullptr, Tuple::String, -1}, + {nullptr, Tuple::String, -1}, + {nullptr, Tuple::String, -1}, +}; + +static_assert(aud::n_elems(field_info) == n_private_fields, + "Update field_data"); + +struct FieldDictEntry +{ + const char * name; + Tuple::Field field; +}; + +/* used for binary search, MUST be in alphabetical order */ +static const FieldDictEntry field_dict[] = { + {"album", Tuple::Album}, + {"album-artist", Tuple::AlbumArtist}, + {"artist", Tuple::Artist}, + {"audio-file", Tuple::AudioFile}, + {"bitrate", Tuple::Bitrate}, + {"codec", Tuple::Codec}, + {"comment", Tuple::Comment}, + {"composer", Tuple::Composer}, + {"copyright", Tuple::Copyright}, + {"date", Tuple::Date}, + {"description", Tuple::Description}, + {"file-ext", Tuple::Suffix}, + {"file-name", Tuple::Basename}, + {"file-path", Tuple::Path}, + {"formatted-title", Tuple::FormattedTitle}, + {"gain-album-gain", Tuple::AlbumGain}, + {"gain-album-peak", Tuple::AlbumPeak}, + {"gain-gain-unit", Tuple::GainDivisor}, + {"gain-peak-unit", Tuple::PeakDivisor}, + {"gain-track-gain", Tuple::TrackGain}, + {"gain-track-peak", Tuple::TrackPeak}, + {"genre", Tuple::Genre}, + {"length", Tuple::Length}, + {"musicbrainz-id", Tuple::MusicBrainzID}, + {"performer", Tuple::Performer}, + {"quality", Tuple::Quality}, + {"segment-end", Tuple::EndTime}, + {"segment-start", Tuple::StartTime}, + {"subsong-id", Tuple::Subtune}, + {"subsong-num", Tuple::NumSubtunes}, + {"title", Tuple::Title}, + {"track-number", Tuple::Track}, + {"year", Tuple::Year}}; + +static_assert(aud::n_elems(field_dict) == Tuple::n_fields, "Update field_dict"); + +static constexpr bool is_valid_field(int field) +{ + return field > Tuple::Invalid && field < Tuple::n_fields; +} + +static int bitcount(uint64_t x) +{ + /* algorithm from http://en.wikipedia.org/wiki/Hamming_weight */ + x -= (x >> 1) & 0x5555555555555555; + x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333); + x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f; + return (x * 0x0101010101010101) >> 56; +} + +static int field_dict_compare(const void * a, const void * b) +{ + return strcmp(((FieldDictEntry *)a)->name, ((FieldDictEntry *)b)->name); +} + +EXPORT Tuple::Field Tuple::field_by_name(const char * name) +{ + FieldDictEntry find = {name, Invalid}; + FieldDictEntry * found = + (FieldDictEntry *)bsearch(&find, field_dict, n_fields, + sizeof(FieldDictEntry), field_dict_compare); + + return found ? found->field : Invalid; +} + +EXPORT const char * Tuple::field_get_name(Field field) +{ + assert(is_valid_field(field)); + return field_info[field].name; +} + +EXPORT Tuple::ValueType Tuple::field_get_type(Field field) +{ + assert(is_valid_field(field)); + return field_info[field].type; +} + +TupleVal * TupleData::lookup(int field, bool add, bool remove) +{ + /* calculate number of preceding fields */ + const uint64_t mask = bitmask(field); + const int pos = bitcount(setmask & (mask - 1)); + + if ((setmask & mask)) + { + if ((add || remove) && field_info[field].type == Tuple::String) + vals[pos].str.~String(); + + if (remove) + { + setmask &= ~mask; + vals.remove(pos, 1); + return nullptr; + } + + return &vals[pos]; + } + + if (!(add || remove) && field_info[field].fallback >= 0) + return lookup(field_info[field].fallback, false, false); + + if (!add) + return nullptr; + + setmask |= mask; + vals.insert(pos, 1); + return &vals[pos]; +} + +void TupleData::set_int(int field, int x) +{ + TupleVal * val = lookup(field, true, false); + val->x = x; +} + +void TupleData::set_str(int field, const char * str) +{ + TupleVal * val = lookup(field, true, false); + new (&val->str) String(str); +} + +void TupleData::set_subtunes(short nsubs, const short * subs) +{ + nsubtunes = nsubs; + + delete[] subtunes; + subtunes = nullptr; + + if (nsubs && subs) + { + subtunes = new short[nsubs]; + memcpy(subtunes, subs, sizeof subtunes[0] * nsubs); + } +} + +TupleData::TupleData() + : setmask(0), subtunes(nullptr), nsubtunes(0), state(Tuple::Initial), + refcount(1) +{ +} + +TupleData::TupleData(const TupleData & other) + : setmask(other.setmask), subtunes(nullptr), nsubtunes(0), + state(other.state), refcount(1) +{ + vals.insert(0, other.vals.len()); + + auto get = other.vals.begin(); + auto set = vals.begin(); + + for (int f = 0; f < n_private_fields; f++) + { + if (other.setmask & bitmask(f)) + { + if (field_info[f].type == Tuple::String) + new (&set->str) String(get->str); + else + set->x = get->x; + + get++; + set++; + } + } + + set_subtunes(other.nsubtunes, other.subtunes); +} + +TupleData::~TupleData() +{ + auto iter = vals.begin(); + + for (int f = 0; f < n_private_fields; f++) + { + if (setmask & bitmask(f)) + { + if (field_info[f].type == Tuple::String) + iter->str.~String(); + + iter++; + } + } + + delete[] subtunes; +} + +bool TupleData::is_same(const TupleData & other) const +{ + if (state != other.state || setmask != other.setmask || + nsubtunes != other.nsubtunes || (!subtunes) != (!other.subtunes)) + return false; + + auto a = vals.begin(); + auto b = other.vals.begin(); + + for (int f = 0; f < n_private_fields; f++) + { + if (setmask & bitmask(f)) + { + bool same; + + if (field_info[f].type == Tuple::String) + same = (a->str == b->str); + else + same = (a->x == b->x); + + if (!same) + return false; + + a++; + b++; + } + } + + if (subtunes && + memcmp(subtunes, other.subtunes, sizeof subtunes[0] * nsubtunes)) + return false; + + return true; +} + +TupleData * TupleData::ref(TupleData * tuple) +{ + if (tuple) + __sync_fetch_and_add(&tuple->refcount, 1); + + return tuple; +} + +void TupleData::unref(TupleData * tuple) +{ + if (tuple && !__sync_sub_and_fetch(&tuple->refcount, 1)) + delete tuple; +} + +TupleData * TupleData::copy_on_write(TupleData * tuple) +{ + if (!tuple) + return new TupleData; + + if (__sync_fetch_and_add(&tuple->refcount, 0) == 1) + return tuple; + + TupleData * copy = new TupleData(*tuple); + unref(tuple); + return copy; +} + +EXPORT Tuple::~Tuple() { TupleData::unref(data); } + +EXPORT bool Tuple::operator==(const Tuple & b) const +{ + if (data == b.data) + return true; + + if (!data || !b.data) + return false; + + return data->is_same(*b.data); +} + +EXPORT Tuple Tuple::ref() const +{ + Tuple tuple; + tuple.data = TupleData::ref(data); + return tuple; +} + +EXPORT Tuple::State Tuple::state() const +{ + return data ? (Tuple::State)data->state : Initial; +} + +EXPORT void Tuple::set_state(State st) +{ + data = TupleData::copy_on_write(data); + data->state = st; +} + +EXPORT Tuple::ValueType Tuple::get_value_type(Field field) const +{ + assert(is_valid_field(field)); + + const auto & info = field_info[field]; + if (data && (data->is_set(field) || + (info.fallback >= 0 && data->is_set(info.fallback)))) + return info.type; + + return Empty; +} + +EXPORT int Tuple::get_int(Field field) const +{ + assert(is_valid_field(field) && field_info[field].type == Int); + + TupleVal * val = data ? data->lookup(field, false, false) : nullptr; + return val ? val->x : -1; +} + +EXPORT String Tuple::get_str(Field field) const +{ + assert(is_valid_field(field) && field_info[field].type == String); + + TupleVal * val = data ? data->lookup(field, false, false) : nullptr; + return val ? val->str : ::String(); +} + +EXPORT void Tuple::set_int(Field field, int x) +{ + assert(is_valid_field(field) && field_info[field].type == Int); + + data = TupleData::copy_on_write(data); + data->set_int(field, x); +} + +EXPORT void Tuple::set_str(Field field, const char * str) +{ + assert(is_valid_field(field) && field_info[field].type == String); + + if (!str) + { + unset(field); + return; + } + + data = TupleData::copy_on_write(data); + + if (g_utf8_validate(str, -1, nullptr)) + data->set_str(field, str); + else + { + StringBuf utf8 = str_to_utf8(str, -1); + data->set_str(field, utf8 ? (const char *)utf8 + : _("(character encoding error)")); + } +} + +EXPORT void Tuple::unset(Field field) +{ + assert(is_valid_field(field)); + + if (!data) + return; + + data = TupleData::copy_on_write(data); + data->lookup(field, false, true); +} + +EXPORT void Tuple::set_filename(const char * filename) +{ + assert(filename); + + data = TupleData::copy_on_write(data); + + // stdin is handled as a special case + if (!strncmp(filename, "stdin://", 8)) + { + data->set_str(Basename, _("Standard input")); + return; + } + + const char *base, *ext, *sub; + int isub; + + uri_parse(filename, &base, &ext, &sub, &isub); + + if (base > filename) + data->set_str(Path, + uri_to_display(str_copy(filename, base - filename))); + if (ext > base) + data->set_str(Basename, + str_to_utf8(str_decode_percent(base, ext - base))); + if (sub > ext + 1) + data->set_str(Suffix, + str_to_utf8(str_decode_percent(ext + 1, sub - ext - 1))); + + if (sub[0]) + data->set_int(Subtune, isub); +} + +EXPORT void Tuple::set_format(const char * format, int chans, int rate, + int brate) +{ + if (format) + set_str(Codec, format); + + StringBuf buf; + + if (chans > 0) + { + if (chans == 1) + buf = str_copy(_("Mono")); + else if (chans == 2) + buf = str_copy(_("Stereo")); + else + buf = str_printf( + dngettext(PACKAGE, "%d channel", "%d channels", chans), chans); + + if (rate > 0) + buf.insert(-1, ", "); + } + + if (rate > 0) + str_append_printf(buf, "%d kHz", rate / 1000); + + if (buf[0]) + set_str(Quality, buf); + + if (brate > 0) + set_int(Bitrate, brate); +} + +EXPORT void Tuple::set_subtunes(short n_subtunes, const short * subtunes) +{ + data = TupleData::copy_on_write(data); + data->set_subtunes(n_subtunes, subtunes); +} + +EXPORT short Tuple::get_n_subtunes() const +{ + return data ? data->nsubtunes : 0; +} + +EXPORT short Tuple::get_nth_subtune(short n) const +{ + if (!data || n < 0 || n >= data->nsubtunes) + return -1; + + return data->subtunes ? data->subtunes[n] : 1 + n; +} + +EXPORT void Tuple::set_gain(Field field, Field unit_field, const char * str) +{ + set_int(field, lround(str_to_double(str) * 1000000)); + set_int(unit_field, 1000000); +} + +/* combining this with get_replay_gain() would be cleaner but would + * require adding a validity flag to ReplayGainInfo, breaking ABI */ +EXPORT bool Tuple::has_replay_gain() const +{ + return get_int(GainDivisor) > 0 && + (data->is_set(AlbumGain) || data->is_set(TrackGain)); +} + +EXPORT ReplayGainInfo Tuple::get_replay_gain() const +{ + ReplayGainInfo gain{}; + + if (!data) + return gain; + + int gain_unit = get_int(GainDivisor); + int peak_unit = get_int(PeakDivisor); + + if (gain_unit > 0) + { + bool have_album = data->is_set(AlbumGain); + bool have_track = data->is_set(TrackGain); + + if (have_album) + gain.album_gain = get_int(AlbumGain) / (float)gain_unit; + if (have_track) + gain.track_gain = get_int(TrackGain) / (float)gain_unit; + + /* fill in missing information if we can */ + if (!have_album && have_track) + gain.album_gain = gain.track_gain; + if (have_album && !have_track) + gain.track_gain = gain.album_gain; + } + + if (peak_unit > 0) + { + bool have_album = data->is_set(AlbumPeak); + bool have_track = data->is_set(TrackPeak); + + if (have_album) + gain.album_peak = get_int(AlbumPeak) / (float)peak_unit; + if (have_track) + gain.track_peak = get_int(TrackPeak) / (float)peak_unit; + + /* fill in missing information if we can */ + if (!have_album && have_track) + gain.album_peak = gain.track_peak; + if (have_album && !have_track) + gain.track_peak = gain.album_peak; + } + + return gain; +} + +EXPORT bool Tuple::fetch_stream_info(VFSFile & stream) +{ + bool updated = false; + int value; + + ::String val = stream.get_metadata("track-name"); + + if (val && val != get_str(Title)) + { + set_str(Title, val); + updated = true; + } + + val = stream.get_metadata("stream-name"); + + if (val && val != get_str(Artist)) + { + set_str(Artist, val); + updated = true; + } + + val = stream.get_metadata("content-bitrate"); + value = val ? atoi(val) / 1000 : 0; + + if (value && value != get_int(Bitrate)) + { + set_int(Bitrate, value); + updated = true; + } + + return updated; +} + +/* Separates the lowest-level folder from a file path. The string passed will + * be modified, and the string returned will use the same memory. May return + * nullptr. */ + +static char * split_folder(char * path, char sep) +{ + char * c; + while ((c = strrchr(path, sep))) + { + *c = 0; + if (c[1]) + return c + 1; + } + + return path[0] ? path : nullptr; +} + +/* These two functions separate the domain name from an internet URL. Examples: + * "http://some.domain.org/folder/file.mp3" -> "some.domain.org" + * "http://some.stream.fm:8000" -> "some.stream.fm" */ + +static const char * find_domain(const char * name) +{ + if (!strncmp(name, "http://", 7)) + return name + 7; + if (!strncmp(name, "https://", 8)) + return name + 8; + if (!strncmp(name, "mms://", 6)) + return name + 6; + + return nullptr; +} + +static StringBuf extract_domain(const char * start) +{ + StringBuf name = str_copy(start); + char * c; + + if ((c = strchr(name, '/'))) + name.resize(c - name); + if ((c = strchr(name, ':'))) + name.resize(c - name); + if ((c = strchr(name, '?'))) + name.resize(c - name); + + return name; +} + +EXPORT void Tuple::generate_fallbacks() +{ + if (!data) + return; + + generate_title(); + + auto artist = get_str(Artist); + auto album = get_str(Album); + auto genre = get_str(Genre); + + if (artist && album) + return; + + data = TupleData::copy_on_write(data); + + // use album artist, if present + if (!artist && (artist = get_str(AlbumArtist))) + { + data->set_str(FallbackArtist, artist); + + if (album) + return; // nothing left to do + } + + auto filepath = get_str(Path); + if (!filepath) + return; + + const char * s; + char sep; + + if (!strcmp(filepath, "cdda://")) + { + // audio CD: + // use "Audio CD" as the album + + if (!album) + data->set_str(FallbackAlbum, _("Audio CD")); + } + else if ((s = find_domain(filepath))) + { + // internet URL: + // use the domain name as the album + + if (!album) + data->set_str(FallbackAlbum, extract_domain(s)); + } + else + { + // any other URI: + // use the top two path elements as the artist and album + + if ((s = strstr(filepath, "://"))) + { + s += 3; + sep = '/'; + } + else + { +#ifdef _WIN32 + if (g_ascii_isalpha(filepath[0]) && filepath[1] == ':') + s = filepath + 2; + else +#endif + s = filepath; + + sep = G_DIR_SEPARATOR; + } + + StringBuf buf = str_copy(s); + + char * first = split_folder(buf, sep); + char * second = + (first && first > buf) ? split_folder(buf, sep) : nullptr; + + // skip common strings and avoid duplicates + for (auto skip : + (const char *[]){"~", "music", artist, album, genre}) + { + if (first && skip && !strcmp_nocase(first, skip)) + { + first = second; + second = nullptr; + } + + if (second && skip && !strcmp_nocase(second, skip)) + second = nullptr; + } + + if (first) + { + if (second && !artist && !album) + { + data->set_str(FallbackArtist, second); + data->set_str(FallbackAlbum, first); + } + else + data->set_str(artist ? FallbackAlbum : FallbackArtist, first); + } + } +} + +EXPORT void Tuple::generate_title() +{ + if (!data) + return; + + auto title = get_str(Title); + if (title) + return; + + data = TupleData::copy_on_write(data); + + auto filepath = get_str(Path); + if (filepath && !strcmp(filepath, "cdda://")) + { + // audio CD: + // use "Track N" as the title + + int subtune = get_int(Subtune); + if (subtune >= 0) + data->set_str(FallbackTitle, str_printf(_("Track %d"), subtune)); + } + else + { + auto filename = get_str(Basename); + data->set_str(FallbackTitle, + filename ? (const char *)filename : _("(unknown title)")); + } +} + +EXPORT void Tuple::delete_fallbacks() +{ + if (!data) + return; + + data = TupleData::copy_on_write(data); + data->lookup(FallbackTitle, false, true); + data->lookup(FallbackArtist, false, true); + data->lookup(FallbackAlbum, false, true); +} diff --git a/src/libaudcore/tuple.h b/src/libaudcore/tuple.h new file mode 100644 index 0000000..0ec1ac1 --- /dev/null +++ b/src/libaudcore/tuple.h @@ -0,0 +1,236 @@ +/* + * tuple.h + * Copyright 2007-2013 Ariadne Conill, Christian Birchinger, Matti Hämäläinen, + * Giacomo Lozito, Eugene Zagidullin, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +/** + * @file tuple.h + * @brief Basic Tuple handling API. + */ + +#ifndef LIBAUDCORE_TUPLE_H +#define LIBAUDCORE_TUPLE_H + +#include <libaudcore/objects.h> + +struct ReplayGainInfo; +struct TupleData; +class PluginHandle; +class VFSFile; + +class Tuple +{ +public: + /* Smart pointer to the actual TupleData struct. + * Uses create-on-write and copy-on-write. */ + + enum State + { + Initial, /* Song info has not yet been read */ + Valid, /* Song info has been successfully read */ + Failed /* Song info could not be read */ + }; + + enum Field + { + Invalid = -1, + + Title = 0, /* Song title */ + Artist, /* Song artist */ + Album, /* Album name */ + AlbumArtist, /* Artist for entire album, if different than song artist + */ + Comment, /* Freeform comment */ + Genre, /* Song's genre */ + Year, /* Year of production, performance, etc. */ + + Composer, /* Composer, if different than artist */ + Performer, /* Performer, if different than artist */ + Copyright, /* Copyright declaration */ + Date, /* Date of production, performance, etc. */ + + Track, /* Track number */ + Length, /* Track length in milliseconds */ + + Bitrate, /* Bitrate in kilobits (1000 bits)/sec */ + Codec, /* Codec name, such as "Ogg Vorbis" */ + Quality, /* String representing quality, such as "Stereo, 44 kHz" */ + + Basename, /* Base filename, not including the folder path */ + Path, /* Folder path, including the trailing "/" */ + Suffix, /* Filename extension, not including the "." */ + + AudioFile, /* URI of audio file, if different from the nominal URI + * (e.g. for a cuesheet entry, where the nominal URI + * points to the .cue file) */ + + Subtune, /* Index number of subtune */ + NumSubtunes, /* Total number of subtunes in the file */ + + StartTime, /* Playback start point (used for cuesheets) */ + EndTime, /* Playback end point (used for cuesheets) */ + + /* Preserving replay gain information accurately is a challenge since + * there are several differents formats around. We use an integer + * fraction, with the denominator stored in the *Divisor fields. For + * example, if AlbumGain is 512 and GainDivisor is 256, then the album + * gain is +2 dB. If TrackPeak is 787 and PeakDivisor is 1000, then the + * peak volume is 0.787 in a -1.0 to 1.0 range. */ + AlbumGain, + AlbumPeak, + TrackGain, + TrackPeak, + GainDivisor, + PeakDivisor, + + /* Title formatted for display; input plugins do not need to set this + field */ + FormattedTitle, + + /* TODO: reorder these at next ABI break! */ + Description, /* Track description */ + MusicBrainzID, /* MusicBrainz identifier */ + + n_fields + }; + + typedef aud::range<Field, Field(0), Field(n_fields - 1)> all_fields; + + enum ValueType + { + String, + Int, + Empty + }; + + static Field field_by_name(const char * name); + static const char * field_get_name(Field field); + static ValueType field_get_type(Field field); + + constexpr Tuple() : data(nullptr) {} + + ~Tuple(); + + Tuple(Tuple && b) : data(b.data) { b.data = nullptr; } + + Tuple & operator=(Tuple && b) + { + return aud::move_assign(*this, std::move(b)); + } + + bool operator==(const Tuple & b) const; + bool operator!=(const Tuple & b) const { return !operator==(b); } + + Tuple ref() const; + + /* Gets/sets the state of the song info. Before setting the state to Valid, + * you should ensure that, at a minimum, set_filename() has been called. */ + State state() const; + void set_state(State st); + + /* Returns the value type of a field if set, otherwise Empty. */ + ValueType get_value_type(Field field) const; + + /* Convenience functions */ + bool valid() const { return state() == Valid; } + bool is_set(Field field) const { return get_value_type(field) != Empty; } + + /* Returns the integer value of a field if set, otherwise -1. If you need + * to distinguish between a value of -1 and an unset value, use + * get_value_type(). */ + int get_int(Field field) const; + + /* Returns the string value of a field if set, otherwise null. */ + ::String get_str(Field field) const; + + /* Sets a field to the integer value <x>. */ + void set_int(Field field, int x); + + /* Sets a field to the string value <str>. If <str> is not valid UTF-8, it + * will be converted according to the user's character set detection rules. + * Equivalent to unset() if <str> is null. */ + void set_str(Field field, const char * str); + + /* Clears any value that a field is currently set to. */ + void unset(Field field); + + /* Parses the URI <filename> and sets Basename, Path, Suffix, and Subtune + * accordingly. */ + void set_filename(const char * filename); + + /* Fills in format-related fields (specifically Codec, Quality, + * and Bitrate). Plugins should use this function instead of setting + * these fields individually to allow a consistent style across file + * formats. <format> should be a brief description such as "Ogg Vorbis", + * "MPEG-1 layer 3", "Audio CD", and so on. <samplerate> is in Hertz. + * <bitrate> is in (decimal) kbps. */ + void set_format(const char * format, int channels, int samplerate, + int bitrate); + + /* In addition to the normal fields, tuples contain an integer array of + * subtune ID numbers. This function sets that array. It also sets + * NumSubtunes to the value <n_subtunes>. */ + void set_subtunes(short n_subtunes, const short * subtunes); + + /* Returns the length of the subtune array. If the array has not been set, + * returns zero. Note that if NumSubtunes is changed after + * set_subtunes() is called, this function returns the value <n_subtunes> + * passed to set_subtunes(), not the value of NumSubtunes. */ + short get_n_subtunes() const; + + /* Returns the <n>th member of the subtune array. */ + short get_nth_subtune(short n) const; + + /* Sets a Replay Gain field pair from a decimal string. */ + void set_gain(Field field, Field unit_field, const char * str); + + /* Returns true if minimal ReplayGainInfo is present. */ + bool has_replay_gain() const; + /* Fills ReplayGainInfo struct from various fields. */ + ReplayGainInfo get_replay_gain() const; + + /* Set various fields based on the ICY metadata of <stream>. Returns true + * if any fields were changed. */ + bool fetch_stream_info(VFSFile & stream); + + /* Guesses the song title, artist, and album, if not already set, from the + * filename. */ + void generate_fallbacks(); + + /* Guesses only the song title, if not already set, from the filename. */ + void generate_title(); + + /* Removes guesses made by generate_fallbacks(). This function should be + * called, for example, before writing a song tag from the tuple. */ + void delete_fallbacks(); + +private: + TupleData * data; +}; + +/* somewhat out of place here */ +struct PlaylistAddItem +{ + String filename; + Tuple tuple; + PluginHandle * decoder; + + PlaylistAddItem copy() const { return {filename, tuple.ref(), decoder}; } +}; + +#endif /* LIBAUDCORE_TUPLE_H */ diff --git a/src/libaudcore/util.cc b/src/libaudcore/util.cc new file mode 100644 index 0000000..96390c9 --- /dev/null +++ b/src/libaudcore/util.cc @@ -0,0 +1,203 @@ +/* + * util.c + * Copyright 2009-2019 John Lindgren and Michał Lipski + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "internal.h" +#include "visualizer.h" + +#include <errno.h> +#include <math.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> + +#include <glib/gstdio.h> + +#include "audstrings.h" +#include "runtime.h" +#include "threads.h" + +const char * get_home_utf8() +{ + static std::once_flag once; + static char * home_utf8; + + auto init = []() { + home_utf8 = + g_filename_to_utf8(g_get_home_dir(), -1, nullptr, nullptr, nullptr); + }; + + std::call_once(once, init); + return home_utf8; +} + +bool dir_foreach(const char * path, DirForeachFunc func, void * user) +{ + GDir * dir = g_dir_open(path, 0, nullptr); + if (!dir) + return false; + + const char * name; + while ((name = g_dir_read_name(dir))) + { + if (func(filename_build({path, name}), name, user)) + break; + } + + g_dir_close(dir); + return true; +} + +String write_temp_file(const void * data, int64_t len) +{ + StringBuf name = filename_build({g_get_tmp_dir(), "audacious-temp-XXXXXX"}); + + int handle = g_mkstemp(name); + if (handle < 0) + { + AUDERR("Error creating temporary file: %s\n", strerror(errno)); + return String(); + } + + while (len) + { + int64_t written = write(handle, data, len); + if (written < 0) + { + AUDERR("Error writing %s: %s\n", (const char *)name, + strerror(errno)); + close(handle); + return String(); + } + + data = (char *)data + written; + len -= written; + } + + if (close(handle) < 0) + { + AUDERR("Error closing %s: %s\n", (const char *)name, strerror(errno)); + return String(); + } + + return String(name); +} + +bool same_basename(const char * a, const char * b) +{ + const char * dot_a = strrchr(a, '.'); + const char * dot_b = strrchr(b, '.'); + int len_a = dot_a ? dot_a - a : strlen(a); + int len_b = dot_b ? dot_b - b : strlen(b); + + return len_a == len_b && !strcmp_nocase(a, b, len_a); +} + +const char * last_path_element(const char * path) +{ + const char * slash = strrchr(path, G_DIR_SEPARATOR); + return (slash && slash[1]) ? slash + 1 : nullptr; +} + +void cut_path_element(char * path, int pos) +{ +#ifdef _WIN32 + if (pos > 3) +#else + if (pos > 1) +#endif + path[pos - 1] = 0; /* overwrite slash */ + else + path[pos] = 0; /* leave [drive letter and] leading slash */ +} + +bool is_cuesheet_entry(const char * filename) +{ + const char *ext, *sub; + uri_parse(filename, nullptr, &ext, &sub, nullptr); + return sub[0] && sub - ext == 4 && !strcmp_nocase(ext, ".cue", 4); +} + +bool is_subtune(const char * filename) +{ + const char * sub; + uri_parse(filename, nullptr, nullptr, &sub, nullptr); + return sub[0]; +} + +StringBuf strip_subtune(const char * filename) +{ + const char * sub; + uri_parse(filename, nullptr, nullptr, &sub, nullptr); + return str_copy(filename, sub - filename); +} + +/* Thomas Wang's 32-bit mix function. See: + * http://web.archive.org/web/20070307172248/http://www.concentric.net/~Ttwang/tech/inthash.htm + */ + +unsigned int32_hash(unsigned val) +{ + val = ~val + (val << 15); + val = val ^ (val >> 12); + val = val + (val << 2); + val = val ^ (val >> 4); + val = val * 2057; + val = val ^ (val >> 16); + return val; +} + +unsigned ptr_hash(const void * ptr) +{ + unsigned addr_low = (uint64_t)(uintptr_t)ptr; + unsigned addr_high = (uint64_t)(uintptr_t)ptr >> 32; + return int32_hash(addr_low + addr_high); +} + +EXPORT void Visualizer::compute_log_xscale(float * xscale, int bands) +{ + for (int i = 0; i <= bands; i++) + xscale[i] = powf(256, (float)i / bands) - 0.5f; +} + +EXPORT float Visualizer::compute_freq_band(const float * freq, + const float * xscale, int band, + int bands) +{ + int a = ceilf(xscale[band]); + int b = floorf(xscale[band + 1]); + float n = 0; + + if (b < a) + n += freq[b] * (xscale[band + 1] - xscale[band]); + else + { + if (a > 0) + n += freq[a - 1] * (a - xscale[band]); + for (; a < b; a++) + n += freq[a]; + if (b < 256) + n += freq[b] * (xscale[band + 1] - b); + } + + /* fudge factor to make the graph have the same overall height as a + 12-band one no matter how many bands there are */ + n *= (float)bands / 12; + + return 20 * log10f(n); +} diff --git a/src/libaudcore/vfs.cc b/src/libaudcore/vfs.cc new file mode 100644 index 0000000..576e3b2 --- /dev/null +++ b/src/libaudcore/vfs.cc @@ -0,0 +1,448 @@ +/* + * vfs.c + * Copyright 2006-2013 Ariadne Conill, Daniel Barkalow, Ralf Ertzinger, + * Yoshiki Yazawa, Matti Hämäläinen, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "vfs.h" + +#define __STDC_FORMAT_MACROS +#include <inttypes.h> +#include <string.h> + +#include "audstrings.h" +#include "i18n.h" +#include "internal.h" +#include "plugin.h" +#include "plugins-internal.h" +#include "probe-buffer.h" +#include "runtime.h" +#include "vfs_local.h" + +/* embedded plugins */ +static LocalTransport local_transport; +static StdinTransport stdin_transport; + +static TransportPlugin * lookup_transport(const char * filename, String & error, + bool * custom_input = nullptr) +{ + StringBuf scheme = uri_get_scheme(filename); + + if (!scheme || !strcmp(scheme, "file")) + return &local_transport; + if (!strcmp(scheme, "stdin")) + return &stdin_transport; + + for (PluginHandle * plugin : aud_plugin_list(PluginType::Transport)) + { + if (!aud_plugin_get_enabled(plugin)) + continue; + + if (transport_plugin_has_scheme(plugin, scheme)) + { + auto tp = (TransportPlugin *)aud_plugin_get_header(plugin); + if (tp) + return tp; + } + } + + if (custom_input) + { + for (PluginHandle * plugin : aud_plugin_list(PluginType::Input)) + { + if (!aud_plugin_get_enabled(plugin)) + continue; + + if (input_plugin_has_key(plugin, InputKey::Scheme, scheme)) + { + *custom_input = true; + return nullptr; + } + } + } + + AUDERR("Unknown URI scheme: %s://\n", (const char *)scheme); + error = String(_("Unknown URI scheme")); + return nullptr; +} + +/** + * Opens a stream from a VFS transport using one of the registered + * #VFSConstructor handlers. + * + * @param path The path or URI to open. + * @param mode The preferred access privileges (not guaranteed). + * @return On success, a #VFSFile object representing the stream. + */ +EXPORT VFSFile::VFSFile(const char * filename, const char * mode) +{ + auto tp = lookup_transport(filename, m_error); + if (!tp) + return; + + VFSImpl * impl = tp->fopen(strip_subtune(filename), mode, m_error); + if (!impl) + return; + + /* enable buffering for read-only handles */ + if (mode[0] == 'r' && !strchr(mode, '+')) + impl = new ProbeBuffer(filename, impl); + + AUDINFO("<%p> open (mode %s) %s\n", impl, mode, filename); + m_filename = String(filename); + m_impl.capture(impl); +} + +EXPORT VFSFile VFSFile::tmpfile() +{ + VFSFile file; + file.m_impl.capture(vfs_tmpfile(file.m_error)); + return file; +} + +/** + * Reads from a VFS stream. + * + * @param ptr A pointer to the destination buffer. + * @param size The size of each element to read. + * @param nmemb The number of elements to read. + * @param file #VFSFile object that represents the VFS stream. + * @return The number of elements succesfully read. + */ +EXPORT int64_t VFSFile::fread(void * ptr, int64_t size, int64_t nmemb) +{ + int64_t readed = m_impl->fread(ptr, size, nmemb); + + AUDDBG("<%p> read %" PRId64 " elements of size %" PRId64 " = %" PRId64 "\n", + m_impl.get(), nmemb, size, readed); + + return readed; +} + +/** + * Writes to a VFS stream. + * + * @param ptr A const pointer to the source buffer. + * @param size The size of each element to write. + * @param nmemb The number of elements to write. + * @param file #VFSFile object that represents the VFS stream. + * @return The number of elements succesfully written. + */ +EXPORT int64_t VFSFile::fwrite(const void * ptr, int64_t size, int64_t nmemb) +{ + int64_t written = m_impl->fwrite(ptr, size, nmemb); + + AUDDBG("<%p> write %" PRId64 " elements of size %" PRId64 " = %" PRId64 + "\n", + m_impl.get(), nmemb, size, written); + + return written; +} + +/** + * Performs a seek in given VFS stream. Standard C-style values + * of whence can be used to indicate desired action. + * + * - SEEK_CUR seeks relative to current stream position. + * - SEEK_SET seeks to given absolute position (relative to stream beginning). + * - SEEK_END sets stream position to current file end. + * + * @param file #VFSFile object that represents the VFS stream. + * @param offset The offset to seek to. + * @param whence Type of the seek: SEEK_CUR, SEEK_SET or SEEK_END. + * @return On success, 0. Otherwise, -1. + */ +EXPORT int VFSFile::fseek(int64_t offset, VFSSeekType whence) +{ + AUDDBG("<%p> seek to %" PRId64 " from %s\n", m_impl.get(), offset, + whence == VFS_SEEK_CUR + ? "current" + : whence == VFS_SEEK_SET + ? "beginning" + : whence == VFS_SEEK_END ? "end" : "invalid"); + + if (m_impl->fseek(offset, whence) == 0) + return 0; + + AUDDBG("<%p> seek failed!\n", m_impl.get()); + + return -1; +} + +/** + * Returns the current position in the VFS stream's buffer. + * + * @param file #VFSFile object that represents the VFS stream. + * @return On success, the current position. Otherwise, -1. + */ +EXPORT int64_t VFSFile::ftell() +{ + int64_t told = m_impl->ftell(); + + AUDDBG("<%p> tell = %" PRId64 "\n", m_impl.get(), told); + + return told; +} + +/** + * Returns whether or not the VFS stream has reached EOF. + * + * @param file #VFSFile object that represents the VFS stream. + * @return On success, whether or not the VFS stream is at EOF. Otherwise, + * false. + */ +EXPORT bool VFSFile::feof() +{ + bool eof = m_impl->feof(); + + AUDDBG("<%p> eof = %s\n", m_impl.get(), eof ? "yes" : "no"); + + return eof; +} + +/** + * Truncates a VFS stream to a certain size. + * + * @param file #VFSFile object that represents the VFS stream. + * @param length The length to truncate at. + * @return On success, 0. Otherwise, -1. + */ +EXPORT int VFSFile::ftruncate(int64_t length) +{ + AUDDBG("<%p> truncate to %" PRId64 "\n", m_impl.get(), length); + + if (m_impl->ftruncate(length) == 0) + return 0; + + AUDDBG("<%p> truncate failed!\n", m_impl.get()); + + return -1; +} + +EXPORT int VFSFile::fflush() +{ + AUDDBG("<%p> flush\n", m_impl.get()); + + if (m_impl->fflush() == 0) + return 0; + + AUDDBG("<%p> flush failed!\n", m_impl.get()); + + return -1; +} + +/** + * Returns size of the file. + * + * @param file #VFSFile object that represents the VFS stream. + * @return On success, the size of the file in bytes. Otherwise, -1. + */ +EXPORT int64_t VFSFile::fsize() +{ + int64_t size = m_impl->fsize(); + + AUDDBG("<%p> size = %" PRId64 "\n", m_impl.get(), size); + + return size; +} + +/** + * Returns metadata about the stream. + * + * @param file #VFSFile object that represents the VFS stream. + * @param field The string constant field name to get. + * @return On success, a copy of the value of the field. Otherwise, nullptr. + */ +EXPORT String VFSFile::get_metadata(const char * field) +{ + return m_impl->get_metadata(field); +} + +EXPORT void VFSFile::set_limit_to_buffer(bool limit) +{ + auto buffer = dynamic_cast<ProbeBuffer *>(m_impl.get()); + if (buffer) + buffer->set_limit_to_buffer(limit); + else + AUDERR("<%p> buffering not supported!\n", m_impl.get()); +} + +EXPORT Index<char> VFSFile::read_all() +{ + constexpr int maxbuf = 16777216; + constexpr int pagesize = 4096; + + Index<char> buf; + int64_t size = fsize(); + int64_t pos = ftell(); + + if (size >= 0 && pos >= 0 && pos <= size) + { + buf.insert(0, aud::min(size - pos, (int64_t)maxbuf)); + size = fread(buf.begin(), 1, buf.len()); + } + else + { + size = 0; + + buf.insert(0, pagesize); + + int64_t readsize; + while ((readsize = fread(&buf[size], 1, buf.len() - size))) + { + size += readsize; + + if (size == buf.len()) + { + if (buf.len() > maxbuf - pagesize) + break; + + buf.insert(-1, pagesize); + } + } + } + + buf.remove(size, -1); + + return buf; +} + +EXPORT bool VFSFile::copy_from(VFSFile & source, int64_t size) +{ + constexpr int bufsize = 65536; + + Index<char> buf; + buf.resize(bufsize); + + while (size < 0 || size > 0) + { + int64_t to_read = (size > 0 && size < bufsize) ? size : bufsize; + int64_t readsize = source.fread(buf.begin(), 1, to_read); + + if (size > 0) + size -= readsize; + + if (fwrite(buf.begin(), 1, readsize) != readsize) + return false; + + if (readsize < to_read) + break; + } + + /* if a fixed size was requested, return true only if all the data was read. + * otherwise, return true only if the end of the source file was reached. */ + return size == 0 || (size < 0 && source.feof()); +} + +EXPORT bool VFSFile::replace_with(VFSFile & source) +{ + if (source.fseek(0, VFS_SEEK_SET) < 0) + return false; + + if (fseek(0, VFS_SEEK_SET) < 0) + return false; + + if (ftruncate(0) < 0) + return false; + + return copy_from(source, -1); +} + +EXPORT bool VFSFile::test_file(const char * filename, VFSFileTest test) +{ + String error; /* discarded */ + return test_file(filename, test, error) == test; +} + +EXPORT VFSFileTest VFSFile::test_file(const char * filename, VFSFileTest test, + String & error) +{ + bool custom_input = false; + auto tp = lookup_transport(filename, error, &custom_input); + + /* for URI schemes handled by input plugins, return 0, indicating that we + * have no way of testing file attributes */ + if (custom_input) + return VFSFileTest(0); + + /* for unsupported URI schemes, return VFS_NO_ACCESS */ + if (!tp) + return VFSFileTest(test & VFS_NO_ACCESS); + + return tp->test_file(strip_subtune(filename), test, error); +} + +EXPORT Index<String> VFSFile::read_folder(const char * filename, String & error) +{ + auto tp = lookup_transport(filename, error); + return tp ? tp->read_folder(filename, error) : Index<String>(); +} + +EXPORT Index<char> VFSFile::read_file(const char * filename, + VFSReadOptions options) +{ + Index<char> text; + + if (!(options & VFS_IGNORE_MISSING) || test_file(filename, VFS_EXISTS)) + { + VFSFile file(filename, "r"); + if (file) + text = file.read_all(); + else + AUDERR("Cannot open %s for reading: %s\n", filename, file.error()); + } + + if ((options & VFS_APPEND_NULL)) + text.append(0); + + return text; +} + +EXPORT bool VFSFile::write_file(const char * filename, const void * data, + int64_t len) +{ + bool written = false; + + VFSFile file(filename, "w"); + if (file) + written = (file.fwrite(data, 1, len) == len && file.fflush() == 0); + else + AUDERR("Cannot open %s for writing: %s\n", filename, file.error()); + + return written; +} + +EXPORT Index<const char *> VFSFile::supported_uri_schemes() +{ + Index<const char *> schemes; + + schemes.append("file"); + schemes.append("stdin"); + + for (PluginHandle * plugin : aud_plugin_list(PluginType::Transport)) + { + if (!aud_plugin_get_enabled(plugin)) + continue; + + for (auto & s : transport_plugin_get_schemes(plugin)) + schemes.append((const char *)s); + } + + schemes.append(nullptr); + + return schemes; +} diff --git a/src/libaudcore/vfs.h b/src/libaudcore/vfs.h new file mode 100644 index 0000000..33c5a65 --- /dev/null +++ b/src/libaudcore/vfs.h @@ -0,0 +1,194 @@ +/* + * vfs.h + * Copyright 2006-2013 Ariadne Conill, Daniel Barkalow, Ralf Ertzinger, + * Yoshiki Yazawa, Matti Hämäläinen, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ +/** + * @file vfs.h + * Main API header for accessing Audacious VFS functionality. + * Provides functions for VFS transport registration and + * file access. + */ + +#ifndef LIBAUDCORE_VFS_H +#define LIBAUDCORE_VFS_H + +#include <stdint.h> + +#include <libaudcore/export.h> +#include <libaudcore/index.h> +#include <libaudcore/objects.h> + +enum VFSFileTest +{ + VFS_IS_REGULAR = (1 << 0), + VFS_IS_SYMLINK = (1 << 1), + VFS_IS_DIR = (1 << 2), + VFS_IS_EXECUTABLE = (1 << 3), + VFS_EXISTS = (1 << 4), + VFS_NO_ACCESS = (1 << 5) +}; + +enum VFSReadOptions +{ + VFS_APPEND_NULL = (1 << 0), + VFS_IGNORE_MISSING = (1 << 1) +}; + +enum VFSSeekType +{ + VFS_SEEK_SET = 0, + VFS_SEEK_CUR = 1, + VFS_SEEK_END = 2 +}; + +#ifdef WANT_VFS_STDIO_COMPAT + +#include <stdio.h> + +constexpr int from_vfs_seek_type(VFSSeekType whence) +{ + return (whence == VFS_SEEK_SET) + ? SEEK_SET + : (whence == VFS_SEEK_CUR) + ? SEEK_CUR + : (whence == VFS_SEEK_END) ? SEEK_END : -1; +} + +constexpr VFSSeekType to_vfs_seek_type(int whence) +{ + return (whence == SEEK_SET) + ? VFS_SEEK_SET + : (whence == SEEK_CUR) + ? VFS_SEEK_CUR + : (whence == SEEK_END) ? VFS_SEEK_END : (VFSSeekType)-1; +} + +#endif // WANT_VFS_STDIO_COMPAT + +// #undef POSIX functions/macros to avoid name conflicts +#undef fread +#undef fseek +#undef ftell +#undef fsize +#undef feof +#undef fwrite +#undef ftruncate +#undef fflush + +class LIBAUDCORE_PUBLIC VFSImpl +{ +public: + VFSImpl() {} + virtual ~VFSImpl() {} + + VFSImpl(const VFSImpl &) = delete; + VFSImpl & operator=(const VFSImpl &) = delete; + + virtual int64_t fread(void * ptr, int64_t size, int64_t nmemb) = 0; + virtual int fseek(int64_t offset, VFSSeekType whence) = 0; + + virtual int64_t ftell() = 0; + virtual int64_t fsize() = 0; + virtual bool feof() = 0; + + virtual int64_t fwrite(const void * ptr, int64_t size, int64_t nmemb) = 0; + virtual int ftruncate(int64_t length) = 0; + virtual int fflush() = 0; + + virtual String get_metadata(const char * field) { return String(); } +}; + +class VFSFile +{ +public: + VFSFile() {} + + VFSFile(const char * filename, VFSImpl * impl) + : m_filename(filename), m_impl(impl) + { + } + + VFSFile(const char * filename, const char * mode); + + /* creates a temporary file (deleted when closed) */ + static VFSFile tmpfile(); + + explicit operator bool() const { return (bool)m_impl; } + const char * filename() const { return m_filename; } + const char * error() const { return m_error; } + + /* basic operations */ + + int64_t fread(void * ptr, int64_t size, int64_t nmemb) + __attribute__((warn_unused_result)); + int fseek(int64_t offset, VFSSeekType whence) + __attribute__((warn_unused_result)); + + int64_t ftell(); + int64_t fsize(); + bool feof(); + + int64_t fwrite(const void * ptr, int64_t size, int64_t nmemb) + __attribute__((warn_unused_result)); + int ftruncate(int64_t length) __attribute__((warn_unused_result)); + int fflush() __attribute__((warn_unused_result)); + + /* used to read e.g. ICY metadata */ + String get_metadata(const char * field); + + /* the VFS layer buffers up to 256 KB of data at the beginning of files + * opened in read-only mode; this function disallows reading outside the + * buffered region (useful for probing the file type) */ + void set_limit_to_buffer(bool limit); + + /* utility functions */ + + /* reads the entire file into memory (limited to 16 MB) */ + Index<char> read_all(); + + /* reads data from another open file and appends it to this one */ + bool copy_from(VFSFile & source, int64_t size = -1); + + /* overwrites the entire file with the contents of another */ + bool replace_with(VFSFile & source); + + /* tests certain attributes of a file without opening it. + * the 2-argument version returns true if all requested tests passed. + * the 3-argument version returns a bitmask indicating which tests passed. + */ + static bool test_file(const char * filename, VFSFileTest test); + static VFSFileTest test_file(const char * filename, VFSFileTest test, + String & error); + + /* returns a sorted list of folder entries (as full URIs) */ + static Index<String> read_folder(const char * filename, String & error); + + /* convenience functions to read/write entire files */ + static Index<char> read_file(const char * filename, VFSReadOptions options); + static bool write_file(const char * filename, const void * data, + int64_t len); + + /* returns a list of supported URI schemes */ + static Index<const char *> supported_uri_schemes(); + +private: + String m_filename, m_error; + SmartPtr<VFSImpl> m_impl; +}; + +#endif /* LIBAUDCORE_VFS_H */ diff --git a/src/libaudcore/vfs_async.cc b/src/libaudcore/vfs_async.cc new file mode 100644 index 0000000..3c22910 --- /dev/null +++ b/src/libaudcore/vfs_async.cc @@ -0,0 +1,93 @@ +/* + * vfs_async.cc + * Copyright 2010-2014 Ariadne Conill and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "vfs_async.h" +#include "list.h" +#include "mainloop.h" +#include "threads.h" +#include "vfs.h" + +struct QueuedData : public ListNode +{ + const String filename; + const VFSConsumer2 cons_f; + + std::thread thread; + Index<char> buf; + + QueuedData(const char * filename, VFSConsumer2 cons_f) + : filename(filename), cons_f(cons_f) + { + } +}; + +static QueuedFunc queued_func; +static List<QueuedData> queue; +static aud::mutex mutex; + +static void send_data(void *) +{ + auto mh = mutex.take(); + + QueuedData * data; + while ((data = queue.head())) + { + queue.remove(data); + + mh.unlock(); + + data->thread.join(); + data->cons_f(data->filename, data->buf); + delete data; + + mh.lock(); + } +} + +static void read_worker(QueuedData * data) +{ + VFSFile file(data->filename, "r"); + if (file) + data->buf = file.read_all(); + + auto mh = mutex.take(); + + if (!queue.head()) + queued_func.queue(send_data, nullptr); + + queue.append(data); +} + +EXPORT void vfs_async_file_get_contents(const char * filename, + VFSConsumer2 cons_f) +{ + auto data = new QueuedData(filename, cons_f); + data->thread = std::thread(read_worker, data); +} + +EXPORT void vfs_async_file_get_contents(const char * filename, + VFSConsumer cons_f, void * user) +{ + auto functor = [cons_f, user](const char * filename, + const Index<char> & buf) { + cons_f(filename, buf, user); + }; + + vfs_async_file_get_contents(filename, functor); +} diff --git a/src/libaudcore/vfs_async.h b/src/libaudcore/vfs_async.h new file mode 100644 index 0000000..5969555 --- /dev/null +++ b/src/libaudcore/vfs_async.h @@ -0,0 +1,36 @@ +/* + * vfs_async.c + * Copyright 2010 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_VFS_ASYNC_H +#define LIBAUDCORE_VFS_ASYNC_H + +#include <functional> +#include <libaudcore/index.h> + +using VFSConsumer2 = + std::function<void(const char * filename, const Index<char> & buf)>; +void vfs_async_file_get_contents(const char * filename, VFSConsumer2 cons_f); + +/* old version -- remove this at next hard API break */ +typedef void (*VFSConsumer)(const char * filename, const Index<char> & buf, + void * user); +void vfs_async_file_get_contents(const char * filename, VFSConsumer cons_f, + void * user); + +#endif diff --git a/src/libaudcore/vfs_local.cc b/src/libaudcore/vfs_local.cc new file mode 100644 index 0000000..d21d3c0 --- /dev/null +++ b/src/libaudcore/vfs_local.cc @@ -0,0 +1,406 @@ +/* + * vfs_local.c + * Copyright 2009-2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <errno.h> +#include <string.h> +#include <unistd.h> + +#include <glib/gstdio.h> + +/* needs to be after system headers for #undef's to take effect */ +#define WANT_VFS_STDIO_COMPAT +#include "vfs_local.h" + +#include "audstrings.h" +#include "i18n.h" +#include "runtime.h" + +#ifdef _WIN32 +#define fseeko fseeko64 +#define ftello ftello64 +#endif + +#define perror(s) AUDERR("%s: %s\n", (const char *)(s), strerror(errno)) + +enum LocalOp +{ + OP_NONE, + OP_READ, + OP_WRITE +}; + +class LocalFile : public VFSImpl +{ +public: + LocalFile(const char * path, FILE * stream) + : m_path(path), m_stream(stream), m_cached_pos(0), m_cached_size(-1), + m_last_op(OP_NONE) + { + } + + ~LocalFile(); + +protected: + int64_t fread(void * ptr, int64_t size, int64_t nmemb); + int fseek(int64_t offset, VFSSeekType whence); + + int64_t ftell(); + int64_t fsize(); + bool feof(); + + int64_t fwrite(const void * ptr, int64_t size, int64_t nmemb); + int ftruncate(int64_t length); + int fflush(); + +private: + String m_path; + FILE * m_stream; + int64_t m_cached_pos; + int64_t m_cached_size; + LocalOp m_last_op; +}; + +VFSImpl * LocalTransport::fopen(const char * uri, const char * mode, + String & error) +{ + StringBuf path = uri_to_filename(uri); + + if (!path) + { + error = String(_("Invalid file name")); + return nullptr; + } + + const char * suffix = ""; + +#ifdef _WIN32 + if (!strchr(mode, 'b')) /* binary mode (Windows) */ + suffix = "b"; +#else + if (!strchr(mode, 'e')) /* close on exec (POSIX) */ + suffix = "e"; +#endif + + StringBuf mode2 = str_concat({mode, suffix}); + + FILE * stream = ::g_fopen(path, mode2); + + if (!stream) + { + int errsave = errno; + + /* try converting to UTF-8, this can solve issues such as: + * 1) legacy filename used on UTF-8 system + * 2) UTF-8 filesystem mounted on legacy system */ + if (errsave == ENOENT) + { + StringBuf path2 = uri_to_filename(uri, false); + if (path2 && strcmp(path, path2)) + stream = ::g_fopen(path2, mode2); + } + + if (!stream) + { + perror(path); + error = String(strerror(errsave)); + return nullptr; + } + } + + return new LocalFile(path, stream); +} + +VFSImpl * StdinTransport::fopen(const char * uri, const char * mode, + String & error) +{ + if (mode[0] != 'r' || strchr(mode, '+')) + { + error = String(_("Invalid access mode")); + return nullptr; + } + + return new LocalFile("(stdin)", stdin); +} + +VFSImpl * vfs_tmpfile(String & error) +{ + FILE * stream = tmpfile(); + + if (!stream) + { + int errsave = errno; + perror("(tmpfile)"); + error = String(strerror(errsave)); + return nullptr; + } + + return new LocalFile("(tmpfile)", stream); +} + +LocalFile::~LocalFile() +{ + // do not close stdin + if (m_stream != stdin && fclose(m_stream) < 0) + perror(m_path); +} + +int64_t LocalFile::fread(void * ptr, int64_t size, int64_t nitems) +{ + if (m_last_op == OP_WRITE) + { + if (::fflush(m_stream) < 0) + { + perror(m_path); + return 0; + } + } + + m_last_op = OP_READ; + + clearerr(m_stream); + + int64_t result = ::fread(ptr, size, nitems, m_stream); + if (result < nitems && ferror(m_stream)) + perror(m_path); + + if (m_cached_pos >= 0) + m_cached_pos += size * result; + + return result; +} + +int64_t LocalFile::fwrite(const void * ptr, int64_t size, int64_t nitems) +{ + if (m_last_op == OP_READ) + { + if (::fflush(m_stream) < 0) + { + perror(m_path); + return 0; + } + } + + m_last_op = OP_WRITE; + + clearerr(m_stream); + + int64_t result = ::fwrite(ptr, size, nitems, m_stream); + if (result < nitems && ferror(m_stream)) + perror(m_path); + + if (m_cached_pos >= 0) + m_cached_pos += size * result; + + if (m_cached_size >= 0 && m_cached_pos >= 0) + m_cached_size = aud::max(m_cached_size, m_cached_pos); + else + m_cached_size = -1; + + return result; +} + +int LocalFile::fseek(int64_t offset, VFSSeekType whence) +{ + int result = fseeko(m_stream, offset, from_vfs_seek_type(whence)); + if (result < 0) + perror(m_path); + + if (result == 0) + { + m_last_op = OP_NONE; + + if (whence == VFS_SEEK_SET) + m_cached_pos = offset; + else if (whence == VFS_SEEK_CUR && m_cached_pos >= 0) + m_cached_pos += offset; + else + m_cached_pos = -1; + } + + return result; +} + +int64_t LocalFile::ftell() +{ + if (m_cached_pos < 0) + m_cached_pos = ftello(m_stream); + + return m_cached_pos; +} + +bool LocalFile::feof() { return ::feof(m_stream); } + +int LocalFile::ftruncate(int64_t length) +{ + if (m_last_op != OP_NONE) + { + if (::fflush(m_stream) < 0) + { + perror(m_path); + return -1; + } + } + + int result = ::ftruncate(fileno(m_stream), length); + if (result < 0) + perror(m_path); + + if (result == 0) + { + m_last_op = OP_NONE; + m_cached_size = length; + } + + return result; +} + +int LocalFile::fflush() +{ + if (m_last_op != OP_WRITE) + return 0; + + int result = ::fflush(m_stream); + if (result < 0) + perror(m_path); + + if (result == 0) + m_last_op = OP_NONE; + + return result; +} + +int64_t LocalFile::fsize() +{ + // size of stdin is unknown + if (m_stream == stdin) + return -1; + + if (m_cached_size < 0) + { + int64_t saved_pos = ftell(); + if (saved_pos < 0) + goto ERR; + + if (fseek(0, VFS_SEEK_END) < 0) + goto ERR; + + m_last_op = OP_NONE; + m_cached_pos = -1; + + int64_t length = ftello(m_stream); + if (length < 0) + goto ERR; + + if (fseek(saved_pos, VFS_SEEK_SET) < 0) + goto ERR; + + m_cached_pos = saved_pos; + m_cached_size = length; + } + + return m_cached_size; + +ERR: + perror(m_path); + return -1; +} + +VFSFileTest LocalTransport::test_file(const char * uri, VFSFileTest test, + String & error) +{ + StringBuf path = uri_to_filename(uri); + if (!path) + { + error = String(_("Invalid file name")); + return VFSFileTest(test & VFS_NO_ACCESS); + } + + int passed = 0; + bool need_stat = true; + GStatBuf st; + +#ifdef S_ISLNK + if (test & VFS_IS_SYMLINK) + { + if (g_lstat(path, &st) < 0) + { + error = String(strerror(errno)); + passed |= VFS_NO_ACCESS; + goto out; + } + + if (S_ISLNK(st.st_mode)) + passed |= VFS_IS_SYMLINK; + else + need_stat = false; + } +#endif + + if (test & (VFS_IS_REGULAR | VFS_IS_DIR | VFS_IS_EXECUTABLE | VFS_EXISTS | + VFS_NO_ACCESS)) + { + if (need_stat && g_stat(path, &st) < 0) + { + error = String(strerror(errno)); + passed |= VFS_NO_ACCESS; + goto out; + } + + if (S_ISREG(st.st_mode)) + passed |= VFS_IS_REGULAR; + if (S_ISDIR(st.st_mode)) + passed |= VFS_IS_DIR; + if (st.st_mode & S_IXUSR) + passed |= VFS_IS_EXECUTABLE; + + passed |= VFS_EXISTS; + } + +out: + return VFSFileTest(test & passed); +} + +Index<String> LocalTransport::read_folder(const char * uri, String & error) +{ + Index<String> entries; + + StringBuf path = uri_to_filename(uri); + if (!path) + { + error = String(_("Invalid file name")); + return entries; + } + + GError * gerr = nullptr; + GDir * folder = g_dir_open(path, 0, &gerr); + if (!folder) + { + error = String(gerr->message); + g_error_free(gerr); + return entries; + } + + const char * name; + while ((name = g_dir_read_name(folder))) + entries.append(String(filename_to_uri(filename_build({path, name})))); + + g_dir_close(folder); + + return entries; +} diff --git a/src/libaudcore/vfs_local.h b/src/libaudcore/vfs_local.h new file mode 100644 index 0000000..e5a9a1c --- /dev/null +++ b/src/libaudcore/vfs_local.h @@ -0,0 +1,46 @@ +/* + * vfs_local.h + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_VFS_LOCAL_H +#define LIBAUDCORE_VFS_LOCAL_H + +#include "plugin.h" + +class LocalTransport : public TransportPlugin +{ +public: + constexpr LocalTransport() : TransportPlugin(PluginInfo(), nullptr) {} + + VFSImpl * fopen(const char * filename, const char * mode, String & error); + VFSFileTest test_file(const char * filename, VFSFileTest test, + String & error); + Index<String> read_folder(const char * filename, String & error); +}; + +class StdinTransport : public TransportPlugin +{ +public: + constexpr StdinTransport() : TransportPlugin(PluginInfo(), nullptr) {} + + VFSImpl * fopen(const char * filename, const char * mode, String & error); +}; + +VFSImpl * vfs_tmpfile(String & error); + +#endif /* LIBAUDCORE_VFS_LOCAL_H */ diff --git a/src/libaudcore/vis-runner.cc b/src/libaudcore/vis-runner.cc new file mode 100644 index 0000000..dde486a --- /dev/null +++ b/src/libaudcore/vis-runner.cc @@ -0,0 +1,219 @@ +/* + * vis_runner.c + * Copyright 2009-2012 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "internal.h" + +#include <assert.h> +#include <stdint.h> +#include <string.h> + +#include "hook.h" +#include "list.h" +#include "mainloop.h" +#include "output.h" +#include "threads.h" + +#define INTERVAL 33 /* milliseconds */ +#define FRAMES_PER_NODE 512 + +struct VisNode : public ListNode +{ + VisNode(int channels, int time) + : channels(channels), time(time), + data(new float[channels * FRAMES_PER_NODE]) + { + } + + ~VisNode() { delete[] data; } + + const int channels; + int time; + float * data; +}; + +static aud::mutex mutex; +static bool enabled = false; +static bool playing = false, paused = false; +static VisNode * current_node = nullptr; +static int current_frames; +static List<VisNode> vis_list; +static List<VisNode> vis_pool; +static QueuedFunc queued_clear; + +static void send_audio(void *) +{ + /* call before locking mutex to avoid deadlock */ + int outputted = output_get_raw_time(); + + auto mh = mutex.take(); + + if (!enabled || !playing || paused) + return; + + VisNode * node = nullptr; + VisNode * next; + + while ((next = vis_list.head())) + { + /* If we are considering a node, stop searching and use it if it is the + * most recent (that is, the next one is in the future). Otherwise, + * consider the next node if it is not in the future by more than the + * length of an interval. */ + if (next->time > outputted + (node ? 0 : INTERVAL)) + break; + + if (node) + vis_pool.prepend(node); + + node = next; + vis_list.remove(node); + } + + if (!node) + return; + + mh.unlock(); + vis_send_audio(node->data, node->channels); + mh.lock(); + + vis_pool.prepend(node); +} + +static void send_clear(void *) { vis_send_clear(); } + +static void flush(aud::mutex::holder &) +{ + delete current_node; + current_node = nullptr; + + vis_list.clear(); + vis_pool.clear(); + + if (enabled) + queued_clear.queue(send_clear, nullptr); +} + +void vis_runner_flush() +{ + auto mh = mutex.take(); + flush(mh); +} + +static void start_stop(aud::mutex::holder & mh, bool new_playing, + bool new_paused) +{ + playing = new_playing; + paused = new_paused; + + queued_clear.stop(); + + if (!enabled || !playing) + flush(mh); + + if (enabled && playing && !paused) + timer_add(TimerRate::Hz30, send_audio); + else + timer_remove(TimerRate::Hz30, send_audio); +} + +void vis_runner_start_stop(bool new_playing, bool new_paused) +{ + auto mh = mutex.take(); + start_stop(mh, new_playing, new_paused); +} + +void vis_runner_pass_audio(int time, const Index<float> & data, int channels, + int rate) +{ + auto mh = mutex.take(); + + if (!enabled || !playing) + return; + + /* We can build a single node from multiple calls; we can also build + * multiple nodes from the same call. If current_node is present, it was + * partly built in the last call and needs to be finished. */ + + int at = 0; + + while (1) + { + if (current_node) + assert(current_node->channels == channels); + else + { + int node_time = time; + + /* There is no partly-built node, so start a new one. Normally + * there will be nodes in the queue already; if so, we want to copy + * audio data from the signal starting at 30 milliseconds after the + * beginning of the most recent node. If there are no nodes in the + * queue, we are at the beginning of the song or had an underrun, + * and we want to copy the earliest audio data we have. */ + + VisNode * tail = vis_list.tail(); + if (tail) + node_time = tail->time + INTERVAL; + + at = channels * (int)((int64_t)(node_time - time) * rate / 1000); + + if (at < 0) + at = 0; + if (at >= data.len()) + break; + + current_node = vis_pool.head(); + + if (current_node) + { + assert(current_node->channels == channels); + vis_pool.remove(current_node); + current_node->time = node_time; + } + else + current_node = new VisNode(channels, node_time); + + current_frames = 0; + } + + /* Copy as much data as we can, limited by how much we have and how much + * space is left in the node. If we cannot fill the node, we return and + * wait for more data to be passed in the next call. If we do fill the + * node, we loop and start building a new one. */ + + int copy = aud::min(data.len() - at, + channels * (FRAMES_PER_NODE - current_frames)); + memcpy(current_node->data + channels * current_frames, &data[at], + sizeof(float) * copy); + current_frames += copy / channels; + + if (current_frames < FRAMES_PER_NODE) + break; + + vis_list.append(current_node); + current_node = nullptr; + } +} + +void vis_runner_enable(bool enable) +{ + auto mh = mutex.take(); + enabled = enable; + start_stop(mh, playing, paused); +} diff --git a/src/libaudcore/visualization.cc b/src/libaudcore/visualization.cc new file mode 100644 index 0000000..1122658 --- /dev/null +++ b/src/libaudcore/visualization.cc @@ -0,0 +1,177 @@ +/* + * visualization.c + * Copyright 2010-2011 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "interface.h" +#include "internal.h" + +#include <string.h> + +#include "plugin.h" +#include "plugins.h" +#include "runtime.h" + +static Index<Visualizer *> visualizers; + +static int running = false; +static int num_enabled = 0; + +EXPORT void aud_visualizer_add(Visualizer * vis) +{ + visualizers.append(vis); + + num_enabled++; + if (num_enabled == 1) + vis_runner_enable(true); +} + +EXPORT void aud_visualizer_remove(Visualizer * vis) +{ + int num_disabled = 0; + + auto is_match = [&](Visualizer * vis2) { + if (vis2 != vis) + return false; + + num_disabled++; + return true; + }; + + visualizers.remove_if(is_match, true); + + num_enabled -= num_disabled; + if (!num_enabled) + vis_runner_enable(false); +} + +void vis_send_clear() +{ + for (Visualizer * vis : visualizers) + vis->clear(); +} + +static void pcm_to_mono(const float * data, float * mono, int channels) +{ + if (channels == 1) + memcpy(mono, data, sizeof(float) * 512); + else + { + float * set = mono; + while (set < &mono[512]) + { + *set++ = (data[0] + data[1]) / 2; + data += channels; + } + } +} + +void vis_send_audio(const float * data, int channels) +{ + auto is_active = [](int type_mask) { + for (Visualizer * vis : visualizers) + { + if ((vis->type_mask & type_mask)) + return true; + } + + return false; + }; + + float mono[512]; + float freq[256]; + + if (is_active(Visualizer::MonoPCM | Visualizer::Freq)) + pcm_to_mono(data, mono, channels); + if (is_active(Visualizer::Freq)) + calc_freq(mono, freq); + + for (Visualizer * vis : visualizers) + { + if ((vis->type_mask & Visualizer::MonoPCM)) + vis->render_mono_pcm(mono); + if ((vis->type_mask & Visualizer::MultiPCM)) + vis->render_multi_pcm(data, channels); + if ((vis->type_mask & Visualizer::Freq)) + vis->render_freq(freq); + } +} + +static bool vis_load(PluginHandle * plugin) +{ + AUDINFO("Activating %s.\n", aud_plugin_get_name(plugin)); + VisPlugin * header = (VisPlugin *)aud_plugin_get_header(plugin); + if (!header) + return false; + + aud_visualizer_add(header); + return true; +} + +static void vis_unload(PluginHandle * plugin) +{ + AUDINFO("Deactivating %s.\n", aud_plugin_get_name(plugin)); + VisPlugin * header = (VisPlugin *)aud_plugin_get_header(plugin); + if (!header) + return; + + header->clear(); + aud_visualizer_remove(header); +} + +void vis_activate(bool activate) +{ + if (!activate == !running) + return; + + for (PluginHandle * plugin : aud_plugin_list(PluginType::Vis)) + { + if (!aud_plugin_get_enabled(plugin)) + continue; + + if (activate) + vis_load(plugin); + else + vis_unload(plugin); + } + + running = activate; +} + +bool vis_plugin_start(PluginHandle * plugin) +{ + VisPlugin * vp = (VisPlugin *)aud_plugin_get_header(plugin); + if (!vp || !vp->init()) + return false; + + if (running) + vis_load(plugin); + + return true; +} + +void vis_plugin_stop(PluginHandle * plugin) +{ + VisPlugin * vp = (VisPlugin *)aud_plugin_get_header(plugin); + if (!vp) + return; + + if (running) + vis_unload(plugin); + + vp->cleanup(); +} diff --git a/src/libaudcore/visualizer.h b/src/libaudcore/visualizer.h new file mode 100644 index 0000000..1a82bd7 --- /dev/null +++ b/src/libaudcore/visualizer.h @@ -0,0 +1,56 @@ +/* + * visualizer.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDCORE_VISUALIZER_H +#define LIBAUDCORE_VISUALIZER_H + +#include <libaudcore/export.h> + +class LIBAUDCORE_PUBLIC Visualizer +{ +public: + enum + { + MonoPCM = (1 << 0), + MultiPCM = (1 << 1), + Freq = (1 << 2) + }; + + const int type_mask; + constexpr Visualizer(int type_mask) : type_mask(type_mask) {} + + /* reset internal state and clear display */ + virtual void clear() = 0; + + /* 512 frames of a single-channel PCM signal */ + virtual void render_mono_pcm(const float * pcm) {} + + /* 512 frames of an interleaved multi-channel PCM signal */ + virtual void render_multi_pcm(const float * pcm, int channels) {} + + /* intensity of frequencies 1/512, 2/512, ..., 256/512 of sample rate */ + virtual void render_freq(const float * freq) {} + + /* common math for rendering a frequency graph (see util.cc) */ + static void compute_log_xscale(float * xscale, int bands); + static float compute_freq_band(const float * freq, const float * xscale, + int band, int bands); +}; + +#endif /* LIBAUDCORE_VISUALIZER_H */ diff --git a/src/libaudgui/Makefile b/src/libaudgui/Makefile new file mode 100644 index 0000000..081bd01 --- /dev/null +++ b/src/libaudgui/Makefile @@ -0,0 +1,67 @@ +SHARED_LIB = ${LIB_PREFIX}audgui${LIB_SUFFIX} +LIB_MAJOR = 5 +LIB_MINOR = 1 + +SRCS = about.cc \ + confirm.cc \ + eq-preset.cc \ + equalizer.cc \ + file-opener.cc \ + images.c \ + infopopup.cc \ + infowin.cc \ + init.cc \ + jump-to-time.cc \ + jump-to-track.cc \ + jump-to-track-cache.cc \ + list.cc \ + menu.cc \ + pixbufs.cc \ + playlists.cc \ + plugin-menu.cc \ + plugin-prefs.cc \ + plugin-view.cc \ + prefs-widget.cc \ + prefs-window.cc \ + preset-browser.cc \ + queue-manager.cc \ + scaled-image.cc \ + status.cc \ + urilist.cc \ + url-opener.cc \ + util.cc + +INCLUDES = libaudgui.h \ + libaudgui-gtk.h \ + list.h \ + menu.h + +CLEAN = images.c images.h + +include ../../buildsys.mk +include ../../extra.mk + +includesubdir = libaudgui + +LD = ${CXX} + +CPPFLAGS := -I.. -I../.. \ + ${CPPFLAGS} \ + ${GLIB_CFLAGS} \ + ${GTK_CFLAGS} + +CFLAGS += ${LIB_CFLAGS} + +LIB_LDFLAGS := -L../libaudcore $(LIB_LDFLAGS) + +LIBS := -laudcore \ + ${LIBS} -lm \ + ${GLIB_LIBS} \ + ${GTK_LIBS} + +pre-depend: images.c images.h + +images.h: images.gresource.xml + glib-compile-resources --sourcedir=../../images --generate-header --target=images.h images.gresource.xml +images.c: images.gresource.xml + glib-compile-resources --sourcedir=../../images --generate-source --target=images.c images.gresource.xml diff --git a/src/libaudgui/about.cc b/src/libaudgui/about.cc new file mode 100644 index 0000000..9787871 --- /dev/null +++ b/src/libaudgui/about.cc @@ -0,0 +1,116 @@ +/* + * about.c + * Copyright 2011-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gtk/gtk.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/i18n.h> +#include <libaudcore/runtime.h> +#include <libaudcore/vfs.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +static const char about_text[] = "<big><b>Audacious " VERSION "</b></big>\n" COPYRIGHT; +static const char website[] = "https://audacious-media-player.org"; + +static GtkWidget * create_credits_notebook (const char * credits, const char * license) +{ + const char * titles[2] = {N_("Credits"), N_("License")}; + const char * text[2] = {credits, license}; + + GtkWidget * notebook = gtk_notebook_new (); + + for (int i = 0; i < 2; i ++) + { + GtkWidget * label = gtk_label_new (_(titles[i])); + + GtkWidget * scrolled = gtk_scrolled_window_new (nullptr, nullptr); + gtk_widget_set_size_request (scrolled, -1, 2 * audgui_get_dpi ()); + gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolled, + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + GtkTextBuffer * buffer = gtk_text_buffer_new (nullptr); + gtk_text_buffer_set_text (buffer, text[i], -1); + GtkWidget * text = gtk_text_view_new_with_buffer (buffer); + gtk_text_view_set_editable ((GtkTextView *) text, false); + gtk_text_view_set_cursor_visible ((GtkTextView *) text, false); + gtk_text_view_set_left_margin ((GtkTextView *) text, 6); + gtk_text_view_set_right_margin ((GtkTextView *) text, 6); + gtk_container_add ((GtkContainer *) scrolled, text); + + gtk_notebook_append_page ((GtkNotebook *) notebook, scrolled, label); + } + + return notebook; +} + +static GtkWidget * create_about_window () +{ + const char * data_dir = aud_get_path (AudPath::DataDir); + + int dpi = audgui_get_dpi (); + + GtkWidget * about_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title ((GtkWindow *) about_window, _("About Audacious")); + gtk_window_set_resizable ((GtkWindow *) about_window, false); + gtk_container_set_border_width ((GtkContainer *) about_window, 3); + + audgui_destroy_on_escape (about_window); + + GtkWidget * vbox = gtk_vbox_new (false, 6); + gtk_container_add ((GtkContainer *) about_window, vbox); + + AudguiPixbuf logo (gdk_pixbuf_new_from_resource_at_scale + ("/org/audacious/about-logo.svg", 4 * dpi, 2 * dpi, true, nullptr)); + GtkWidget * image = gtk_image_new_from_pixbuf (logo.get ()); + gtk_box_pack_start ((GtkBox *) vbox, image, false, false, 0); + + GtkWidget * label = gtk_label_new (nullptr); + gtk_label_set_markup ((GtkLabel *) label, about_text); + gtk_label_set_justify ((GtkLabel *) label, GTK_JUSTIFY_CENTER); + gtk_box_pack_start ((GtkBox *) vbox, label, false, false, 0); + + GtkWidget * align = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_box_pack_start ((GtkBox *) vbox, align, false, false, 0); + + GtkWidget * button = gtk_link_button_new (website); + gtk_container_add ((GtkContainer *) align, button); + + auto credits = VFSFile::read_file (filename_build ({data_dir, "AUTHORS"}), VFS_APPEND_NULL); + auto license = VFSFile::read_file (filename_build ({data_dir, "COPYING"}), VFS_APPEND_NULL); + + GtkWidget * notebook = create_credits_notebook (credits.begin (), license.begin ()); + gtk_widget_set_size_request (notebook, 6 * dpi, 2 * dpi); + gtk_box_pack_start ((GtkBox *) vbox, notebook, true, true, 0); + + return about_window; +} + +EXPORT void audgui_show_about_window () +{ + if (! audgui_reshow_unique_window (AUDGUI_ABOUT_WINDOW)) + audgui_show_unique_window (AUDGUI_ABOUT_WINDOW, create_about_window ()); +} + +EXPORT void audgui_hide_about_window () +{ + audgui_hide_unique_window (AUDGUI_ABOUT_WINDOW); +} diff --git a/src/libaudgui/confirm.cc b/src/libaudgui/confirm.cc new file mode 100644 index 0000000..1f9b235 --- /dev/null +++ b/src/libaudgui/confirm.cc @@ -0,0 +1,98 @@ +/* + * confirm.c + * Copyright 2010-2013 John Lindgren and Thomas Lange + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gtk/gtk.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/drct.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/interface.h> +#include <libaudcore/playlist.h> +#include <libaudcore/runtime.h> + +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +static void show_question_dialog (const char * title, const char * text, + GtkWidget * widget, GtkWidget * action) +{ + auto cancel = audgui_button_new (_("_Cancel"), "process-stop", nullptr, nullptr); + auto dialog = audgui_dialog_new (GTK_MESSAGE_QUESTION, title, text, action, cancel); + + audgui_dialog_add_widget (dialog, widget); + gtk_widget_show_all (dialog); +} + +static void no_confirm_cb (GtkToggleButton * toggle, void * config) +{ + aud_set_bool ("audgui", (const char *) config, gtk_toggle_button_get_active (toggle)); +} + +static void show_confirm_dialog (const char * title, const char * text, + GtkWidget * action, const char * config) +{ + auto check = gtk_check_button_new_with_mnemonic (_("_Don’t ask again")); + g_signal_connect (check, "toggled", (GCallback) no_confirm_cb, (void *) config); + + show_question_dialog (title, text, check, action); +} + +static void confirm_delete_cb (void * data) +{ + aud::from_ptr<Playlist> (data).remove_playlist (); +} + +EXPORT void audgui_confirm_playlist_delete (Playlist playlist) +{ + if (aud_get_bool ("audgui", "no_confirm_playlist_delete")) + { + playlist.remove_playlist (); + return; + } + + StringBuf text = str_printf (_("Do you want to permanently remove “%s”?"), + (const char *) playlist.get_title ()); + + auto button = audgui_button_new (_("_Remove"), "edit-delete", + confirm_delete_cb, aud::to_ptr (playlist)); + + show_confirm_dialog (_("Remove Playlist"), text, button, "no_confirm_playlist_delete"); +} + +static void rename_cb (void * entry) +{ + void * data = g_object_get_data ((GObject *) entry, "playlist"); + auto playlist = aud::from_ptr<Playlist> (data); + + playlist.set_title (gtk_entry_get_text ((GtkEntry *) entry)); +} + +EXPORT void audgui_show_playlist_rename (Playlist playlist) +{ + auto entry = gtk_entry_new (); + gtk_entry_set_text ((GtkEntry *) entry, playlist.get_title ()); + gtk_entry_set_activates_default ((GtkEntry *) entry, true); + + g_object_set_data ((GObject *) entry, "playlist", aud::to_ptr (playlist)); + + auto text = _("What would you like to call this playlist?"); + auto button = audgui_button_new (_("_Rename"), "insert-text", rename_cb, entry); + show_question_dialog (_("Rename Playlist"), text, entry, button); +} diff --git a/src/libaudgui/eq-preset.cc b/src/libaudgui/eq-preset.cc new file mode 100644 index 0000000..cdffa77 --- /dev/null +++ b/src/libaudgui/eq-preset.cc @@ -0,0 +1,381 @@ +/* + * eq-preset.c + * Copyright 2015 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <string.h> + +#include <libaudcore/equalizer.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/index.h> +#include <libaudcore/interface.h> +#include <libaudcore/runtime.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" +#include "list.h" +#include "menu.h" +#include "preset-browser.h" + +struct PresetItem { + EqualizerPreset preset; + bool selected; +}; + +static Index<PresetItem> preset_list; +static bool changes_made; + +static GtkWidget * list, * entry, * add, * revert; + +static void get_value (void *, int row, int column, GValue * value) +{ + g_return_if_fail (row >= 0 && row < preset_list.len ()); + g_value_set_string (value, preset_list[row].preset.name); +} + +static bool get_selected (void *, int row) +{ + g_return_val_if_fail (row >= 0 && row < preset_list.len (), false); + return preset_list[row].selected; +} + +static void set_selected (void *, int row, bool selected) +{ + g_return_if_fail (row >= 0 && row < preset_list.len ()); + preset_list[row].selected = selected; +} + +static void select_all (void *, bool selected) +{ + for (PresetItem & item : preset_list) + item.selected = selected; +} + +static void activate_preset (const EqualizerPreset & preset) +{ + aud_eq_apply_preset (preset); + aud_set_bool ("equalizer_active", true); +} + +static void activate_row (void *, int row) +{ + g_return_if_fail (row >= 0 && row < preset_list.len ()); + activate_preset (preset_list[row].preset); +} + +static void focus_change (void *, int row) +{ + g_return_if_fail (row >= 0 && row < preset_list.len ()); + gtk_entry_set_text ((GtkEntry *) entry, preset_list[row].preset.name); +} + +static const AudguiListCallbacks callbacks = { + get_value, + get_selected, + set_selected, + select_all, + activate_row, + nullptr, // right_click + nullptr, // shift_rows + nullptr, // data_type + nullptr, // get_data + nullptr, // receive_data + nullptr, // mouse_motion + nullptr, // mouse_leave + focus_change +}; + +static void populate_list () +{ + auto presets = aud_eq_read_presets ("eq.preset"); + for (const EqualizerPreset & preset : presets) + preset_list.append (preset, false); +} + +static void save_list () +{ + Index<EqualizerPreset> presets; + for (const PresetItem & item : preset_list) + presets.append (item.preset); + + presets.sort ([] (const EqualizerPreset & a, const EqualizerPreset & b) + { return strcmp (a.name, b.name); }); + + aud_eq_write_presets (presets, "eq.preset"); +} + +static int find_by_name (const char * name) +{ + for (PresetItem & item : preset_list) + { + if (! strcmp (item.preset.name, name)) + return & item - preset_list.begin (); + } + + return -1; +} + +static const EqualizerPreset * find_one_selected () +{ + const EqualizerPreset * preset = nullptr; + + for (PresetItem & item : preset_list) + { + if (item.selected) + { + if (preset) + { + preset = nullptr; + break; + } + + preset = & item.preset; + } + } + + if (! preset) + aud_ui_show_error (_("Please select one preset to export.")); + + return preset; +} + +static void text_changed () +{ + const char * name = gtk_entry_get_text ((GtkEntry *) entry); + gtk_widget_set_sensitive (add, (bool) name[0]); +} + +static void add_from_entry () +{ + const char * name = gtk_entry_get_text ((GtkEntry *) entry); + int idx = find_by_name (name); + + if (idx < 0) + { + idx = preset_list.len (); + preset_list.append (EqualizerPreset {String (name)}); + audgui_list_insert_rows (list, idx, 1); + } + + aud_eq_update_preset (preset_list[idx].preset); + + select_all (nullptr, false); + preset_list[idx].selected = true; + + audgui_list_update_selection (list, 0, preset_list.len ()); + audgui_list_set_focus (list, idx); + + changes_made = true; + gtk_widget_set_sensitive (revert, true); +} + +static void delete_selected () +{ + auto is_selected = [] (const PresetItem & item) + { return item.selected; }; + + int old_len = preset_list.len (); + preset_list.remove_if (is_selected); + int new_len = preset_list.len (); + + if (old_len != new_len) + { + audgui_list_delete_rows (list, 0, old_len); + audgui_list_insert_rows (list, 0, new_len); + + changes_made = true; + gtk_widget_set_sensitive (revert, true); + } +} + +static void revert_changes () +{ + audgui_list_delete_rows (list, 0, preset_list.len ()); + + preset_list.clear (); + populate_list (); + + audgui_list_insert_rows (list, 0, preset_list.len ()); + + changes_made = false; + gtk_widget_set_sensitive (revert, false); +} + +static void do_save_file (void) +{ + auto preset = find_one_selected (); + if (preset) + eq_preset_save_file (* preset); +} + +static void do_save_eqf (void) +{ + auto preset = find_one_selected (); + if (preset) + eq_preset_save_eqf (* preset); +} + +static void cleanup_eq_preset_window () +{ + // also hide the preset browser window + audgui_hide_unique_window (AUDGUI_PRESET_BROWSER_WINDOW); + + if (changes_made) + { + save_list (); + changes_made = false; + } + + preset_list.clear (); + + list = nullptr; + entry = nullptr; + add = nullptr; + revert = nullptr; +} + +static GtkWidget * create_menu_bar () +{ + static const AudguiMenuItem import_items[] = { + MenuCommand (N_("Preset File ..."), nullptr, 0, (GdkModifierType) 0, eq_preset_load_file), + MenuCommand (N_("EQF File ..."), nullptr, 0, (GdkModifierType) 0, eq_preset_load_eqf) + }; + + static const AudguiMenuItem export_items[] = { + MenuCommand (N_("Preset File ..."), nullptr, 0, (GdkModifierType) 0, do_save_file), + MenuCommand (N_("EQF File ..."), nullptr, 0, (GdkModifierType) 0, do_save_eqf) + }; + + static const AudguiMenuItem menus[] = { + MenuSub (N_("Import"), nullptr, {import_items}), + MenuSub (N_("Export"), nullptr, {export_items}) + }; + + GtkWidget * bar = gtk_menu_bar_new (); + audgui_menu_init (bar, {menus}, nullptr); + return bar; +} + +static GtkWidget * create_eq_preset_window () +{ + int dpi = audgui_get_dpi (); + + populate_list (); + + GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title ((GtkWindow *) window, _("Equalizer Presets")); + gtk_window_set_type_hint ((GtkWindow *) window, GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_default_size ((GtkWindow *) window, 3 * dpi, 3 * dpi); + audgui_destroy_on_escape (window); + + g_signal_connect (window, "destroy", (GCallback) cleanup_eq_preset_window, nullptr); + + GtkWidget * outer = gtk_vbox_new (false, 0); + gtk_container_add ((GtkContainer *) window, outer); + + gtk_box_pack_start ((GtkBox *) outer, create_menu_bar (), false, false, 0); + + GtkWidget * vbox = gtk_vbox_new (false, 6); + gtk_container_set_border_width ((GtkContainer *) vbox, 6); + gtk_box_pack_start ((GtkBox *) outer, vbox, true, true, 0); + + GtkWidget * hbox = gtk_hbox_new (false, 6); + gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 0); + + entry = gtk_entry_new (); + gtk_box_pack_start ((GtkBox *) hbox, entry, true, true, 0); + + add = audgui_button_new (_("Save Preset"), "document-save", + (AudguiCallback) add_from_entry, nullptr); + gtk_widget_set_sensitive (add, false); + gtk_box_pack_start ((GtkBox *) hbox, add, false, false, 0); + + g_signal_connect (entry, "activate", (GCallback) add_from_entry, nullptr); + g_signal_connect (entry, "changed", (GCallback) text_changed, nullptr); + + GtkWidget * scrolled = gtk_scrolled_window_new (nullptr, nullptr); + gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, GTK_SHADOW_IN); + gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolled, + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_box_pack_start ((GtkBox *) vbox, scrolled, true, true, 0); + + list = audgui_list_new (& callbacks, nullptr, preset_list.len ()); + gtk_tree_view_set_headers_visible ((GtkTreeView *) list, false); + audgui_list_add_column (list, nullptr, 0, G_TYPE_STRING, -1); + gtk_container_add ((GtkContainer *) scrolled, list); + + GtkWidget * hbox2 = gtk_hbox_new (false, 6); + gtk_box_pack_start ((GtkBox *) vbox, hbox2, false, false, 0); + + GtkWidget * remove = audgui_button_new (_("Delete Selected"), "edit-delete", + (AudguiCallback) delete_selected, nullptr); + gtk_box_pack_start ((GtkBox *) hbox2, remove, false, false, 0); + + revert = audgui_button_new (_("Revert Changes"), "edit-undo", + (AudguiCallback) revert_changes, nullptr); + gtk_widget_set_sensitive (revert, false); + gtk_box_pack_end ((GtkBox *) hbox2, revert, false, false, 0); + + return window; +} + +EXPORT void audgui_show_eq_preset_window () +{ + if (! audgui_reshow_unique_window (AUDGUI_EQ_PRESET_WINDOW)) + audgui_show_unique_window (AUDGUI_EQ_PRESET_WINDOW, create_eq_preset_window ()); +} + +static void merge_presets (const Index<EqualizerPreset> & presets) +{ + /* eliminate duplicates (could be optimized) */ + for (const EqualizerPreset & preset : presets) + { + auto is_duplicate = [& preset] (const PresetItem & item) + { return item.preset.name == preset.name; }; + + preset_list.remove_if (is_duplicate); + } + + /* deselect existing presets */ + for (auto & item : preset_list) + item.selected = false; + + /* append and select new presets */ + for (const EqualizerPreset & preset : presets) + preset_list.append (preset, true); + + /* if a single preset was imported, activate it */ + if (presets.len () == 1) + activate_preset (presets[0]); +} + +EXPORT void audgui_import_eq_presets (const Index<EqualizerPreset> & presets) +{ + // make sure the presets window is displayed + if (! list) + return; + + audgui_list_delete_rows (list, 0, preset_list.len ()); + merge_presets (presets); + audgui_list_insert_rows (list, 0, preset_list.len ()); + audgui_list_set_focus (list, preset_list.len () - 1); + + changes_made = true; + gtk_widget_set_sensitive (revert, true); +} diff --git a/src/libaudgui/equalizer.cc b/src/libaudgui/equalizer.cc new file mode 100644 index 0000000..a6d6640 --- /dev/null +++ b/src/libaudgui/equalizer.cc @@ -0,0 +1,185 @@ +/* + * equalizer.c + * Copyright 2010-2015 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <math.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/equalizer.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/runtime.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +static void on_off_cb (GtkToggleButton * on_off) +{ + aud_set_bool ("equalizer_active", gtk_toggle_button_get_active (on_off)); +} + +static void on_off_update (void *, GtkWidget * on_off) +{ + gtk_toggle_button_set_active ((GtkToggleButton *) on_off, aud_get_bool + (nullptr, "equalizer_active")); +} + +static GtkWidget * create_on_off () +{ + GtkWidget * on_off = gtk_check_button_new_with_mnemonic (_("_Enable")); + g_signal_connect (on_off, "toggled", (GCallback) on_off_cb, nullptr); + hook_associate ("set equalizer_active", (HookFunction) on_off_update, on_off); + + on_off_update (nullptr, on_off); + return on_off; +} + +static void reset_to_zero () +{ + aud_eq_apply_preset (EqualizerPreset ()); +} + +static void slider_moved (GtkRange * slider) +{ + int band = GPOINTER_TO_INT (g_object_get_data ((GObject *) slider, "band")); + double value = round (gtk_range_get_value (slider)); + + if (band == -1) + aud_set_double ("equalizer_preamp", value); + else + aud_eq_set_band (band, value); +} + +static GtkWidget * create_slider (const char * name, int band, GtkWidget * hbox) +{ + GtkWidget * vbox = gtk_vbox_new (false, 6); + + GtkWidget * label = gtk_label_new (name); + gtk_label_set_angle ((GtkLabel *) label, 90); + gtk_box_pack_start ((GtkBox *) vbox, label, true, false, 0); + + GtkWidget * slider = gtk_vscale_new_with_range (-AUD_EQ_MAX_GAIN, AUD_EQ_MAX_GAIN, 1); + gtk_scale_set_draw_value ((GtkScale *) slider, true); + gtk_scale_set_value_pos ((GtkScale *) slider, GTK_POS_BOTTOM); + gtk_range_set_inverted ((GtkRange *) slider, true); + gtk_widget_set_size_request (slider, -1, audgui_get_dpi () * 5 / 4); + + g_object_set_data ((GObject *) slider, "band", GINT_TO_POINTER (band)); + g_signal_connect (slider, "value-changed", (GCallback) slider_moved, nullptr); + + gtk_box_pack_start ((GtkBox *) vbox, slider, false, false, 0); + gtk_box_pack_start ((GtkBox *) hbox, vbox, false, false, 0); + + return slider; +} + +static void set_slider (GtkWidget * slider, double value) +{ + g_signal_handlers_block_by_func (slider, (void *) slider_moved, nullptr); + gtk_range_set_value ((GtkRange *) slider, round (value)); + g_signal_handlers_unblock_by_func (slider, (void *) slider_moved, nullptr); +} + +static void update_sliders (void *, GtkWidget * window) +{ + GtkWidget * preamp = (GtkWidget *) g_object_get_data ((GObject *) window, "preamp"); + set_slider (preamp, aud_get_double ("equalizer_preamp")); + + double values[AUD_EQ_NBANDS]; + aud_eq_get_bands (values); + + for (int i = 0; i < AUD_EQ_NBANDS; i ++) + { + StringBuf slider_id = str_printf ("slider%d", i); + GtkWidget * slider = (GtkWidget *) g_object_get_data ((GObject *) window, slider_id); + set_slider (slider, values[i]); + } +} + +static void destroy_cb () +{ + hook_dissociate ("set equalizer_active", (HookFunction) on_off_update); + hook_dissociate ("set equalizer_bands", (HookFunction) update_sliders); + hook_dissociate ("set equalizer_preamp", (HookFunction) update_sliders); +} + +static GtkWidget * create_window () +{ + const char * const names[AUD_EQ_NBANDS] = {N_("31 Hz"), N_("63 Hz"), + N_("125 Hz"), N_("250 Hz"), N_("500 Hz"), N_("1 kHz"), N_("2 kHz"), + N_("4 kHz"), N_("8 kHz"), N_("16 kHz")}; + + GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title ((GtkWindow *) window, _("Equalizer")); + gtk_window_set_type_hint ((GtkWindow *) window, GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_resizable ((GtkWindow *) window, false); + gtk_container_set_border_width ((GtkContainer *) window, 6); + audgui_destroy_on_escape (window); + + GtkWidget * vbox = gtk_vbox_new (false, 6); + gtk_container_add ((GtkContainer *) window, vbox); + + GtkWidget * top_row = gtk_hbox_new (false, 6); + gtk_box_pack_start ((GtkBox *) vbox, top_row, false, false, 0); + + gtk_box_pack_start ((GtkBox *) top_row, create_on_off (), false, false, 0); + + GtkWidget * presets = audgui_button_new (_("Presets ..."), nullptr, + (AudguiCallback) audgui_show_eq_preset_window, nullptr); + gtk_box_pack_end ((GtkBox *) top_row, presets, false, false, 0); + + GtkWidget * zero = audgui_button_new (_("Reset to Zero"), nullptr, + (AudguiCallback) reset_to_zero, nullptr); + gtk_box_pack_end ((GtkBox *) top_row, zero, false, false, 0); + + GtkWidget * hbox = gtk_hbox_new (false, 6); + gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 0); + + GtkWidget * preamp = create_slider (_("Preamp"), -1, hbox); + g_object_set_data ((GObject *) window, "preamp", preamp); + + gtk_box_pack_start ((GtkBox *) hbox, gtk_vseparator_new (), false, false, 0); + + for (int i = 0; i < AUD_EQ_NBANDS; i ++) + { + StringBuf slider_id = str_printf ("slider%d", i); + GtkWidget * slider = create_slider (_(names[i]), i, hbox); + g_object_set_data ((GObject *) window, slider_id, slider); + } + + update_sliders (nullptr, window); + + hook_associate ("set equalizer_preamp", (HookFunction) update_sliders, window); + hook_associate ("set equalizer_bands", (HookFunction) update_sliders, window); + + g_signal_connect (window, "destroy", (GCallback) destroy_cb, nullptr); + + return window; +} + +EXPORT void audgui_show_equalizer_window () +{ + if (! audgui_reshow_unique_window (AUDGUI_EQUALIZER_WINDOW)) + audgui_show_unique_window (AUDGUI_EQUALIZER_WINDOW, create_window ()); +} + +EXPORT void audgui_hide_equalizer_window () +{ + audgui_hide_unique_window (AUDGUI_EQUALIZER_WINDOW); +} diff --git a/src/libaudgui/file-opener.cc b/src/libaudgui/file-opener.cc new file mode 100644 index 0000000..adaab4f --- /dev/null +++ b/src/libaudgui/file-opener.cc @@ -0,0 +1,156 @@ +/* + * file-opener.c + * Copyright 2007-2013 Michael Färber and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gtk/gtk.h> + +#define AUD_GLIB_INTEGRATION +#include <libaudcore/drct.h> +#include <libaudcore/i18n.h> +#include <libaudcore/runtime.h> +#include <libaudcore/tuple.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +static Index<PlaylistAddItem> get_files (GtkWidget * chooser) +{ + Index<PlaylistAddItem> index; + GSList * list = gtk_file_chooser_get_uris ((GtkFileChooser *) chooser); + + for (GSList * node = list; node; node = node->next) + index.append (String ((const char *) node->data)); + + g_slist_free_full (list, g_free); + return index; +} + +static void open_cb (void * data) +{ + GtkWidget * chooser = (GtkWidget *) data; + Index<PlaylistAddItem> files = get_files (chooser); + gboolean open = GPOINTER_TO_INT (g_object_get_data ((GObject *) chooser, "do-open")); + + if (open) + aud_drct_pl_open_list (std::move (files)); + else + aud_drct_pl_add_list (std::move (files), -1); + + GtkWidget * toggle = (GtkWidget *) g_object_get_data ((GObject *) chooser, "toggle-button"); + if (gtk_toggle_button_get_active ((GtkToggleButton *) toggle)) + audgui_hide_filebrowser (); +} + +static void destroy_cb (GtkWidget * chooser) +{ + CharPtr path (gtk_file_chooser_get_current_folder ((GtkFileChooser *) chooser)); + if (path) + aud_set_str ("audgui", "filesel_path", path); +} + +static void toggled_cb (GtkToggleButton * toggle, void * option) +{ + aud_set_bool ("audgui", (const char *) option, gtk_toggle_button_get_active (toggle)); +} + +static GtkWidget * create_filebrowser (gboolean open) +{ + const char * window_title, * verb, * icon, * toggle_text, * option; + + if (open) + { + window_title = _("Open Files"); + verb = _("_Open"); + icon = "document-open"; + toggle_text = _("Close _dialog on open"); + option = "close_dialog_open"; + } + else + { + window_title = _("Add Files"); + verb = _("_Add"); + icon = "list-add"; + toggle_text = _("Close _dialog on add"); + option = "close_dialog_add"; + } + + int dpi = audgui_get_dpi (); + + GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_type_hint ((GtkWindow *) window, GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_title ((GtkWindow *) window, window_title); + gtk_window_set_default_size ((GtkWindow *) window, 7 * dpi, 5 * dpi); + gtk_container_set_border_width ((GtkContainer *) window, 10); + + GtkWidget * vbox = gtk_vbox_new (false, 0); + gtk_container_add ((GtkContainer *) window, vbox); + + GtkWidget * chooser = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_OPEN); + gtk_file_chooser_set_local_only ((GtkFileChooser *) chooser, false); + gtk_file_chooser_set_select_multiple ((GtkFileChooser *) chooser, true); + + String path = aud_get_str ("audgui", "filesel_path"); + if (path[0]) + gtk_file_chooser_set_current_folder ((GtkFileChooser *) chooser, path); + + gtk_box_pack_start ((GtkBox *) vbox, chooser, true, true, 3); + + GtkWidget * hbox = gtk_hbox_new (false, 0); + gtk_box_pack_end ((GtkBox *) vbox, hbox, false, false, 3); + + GtkWidget * toggle = gtk_check_button_new_with_mnemonic (toggle_text); + gtk_toggle_button_set_active ((GtkToggleButton *) toggle, aud_get_bool ("audgui", option)); + g_signal_connect (toggle, "toggled", (GCallback) toggled_cb, (void *) option); + gtk_box_pack_start ((GtkBox *) hbox, toggle, true, true, 0); + + GtkWidget * bbox = gtk_hbutton_box_new (); + gtk_button_box_set_layout ((GtkButtonBox *) bbox, GTK_BUTTONBOX_END); + gtk_box_set_spacing ((GtkBox *) bbox, 6); + gtk_box_pack_end ((GtkBox *) hbox, bbox, true, true, 0); + + GtkWidget * action_button = audgui_button_new (verb, icon, open_cb, chooser); + GtkWidget * close_button = audgui_button_new (_("_Close"), "window-close", + (AudguiCallback) audgui_hide_filebrowser, nullptr); + + gtk_container_add ((GtkContainer *) bbox, close_button); + gtk_container_add ((GtkContainer *) bbox, action_button); + + gtk_widget_set_can_default (action_button, true); + gtk_widget_grab_default (action_button); + + g_object_set_data ((GObject *) chooser, "toggle-button", toggle); + g_object_set_data ((GObject *) chooser, "do-open", GINT_TO_POINTER (open)); + + g_signal_connect (chooser, "file-activated", (GCallback) open_cb, nullptr); + g_signal_connect (chooser, "destroy", (GCallback) destroy_cb, nullptr); + + audgui_destroy_on_escape (window); + + return window; +} + +EXPORT void audgui_run_filebrowser (bool open) +{ + audgui_show_unique_window (AUDGUI_FILEBROWSER_WINDOW, create_filebrowser (open)); +} + +EXPORT void audgui_hide_filebrowser () +{ + audgui_hide_unique_window (AUDGUI_FILEBROWSER_WINDOW); +} diff --git a/src/libaudgui/images.gresource.xml b/src/libaudgui/images.gresource.xml new file mode 100644 index 0000000..83441eb --- /dev/null +++ b/src/libaudgui/images.gresource.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<gresources> + <gresource prefix="/org/audacious"> + <file>about-logo.svg</file> + <file>application-exit.svg</file> + <file>applications-graphics.svg</file> + <file>applications-internet.svg</file> + <file>applications-system.svg</file> + <file>appointment-new.svg</file> + <file>audacious.svg</file> + <file>audio-card.svg</file> + <file>audio-volume-high.svg</file> + <file>audio-volume-low.svg</file> + <file>audio-volume-medium.svg</file> + <file>audio-volume-muted.svg</file> + <file>audio-x-generic.svg</file> + <file>dialog-error.svg</file> + <file>dialog-information.svg</file> + <file>dialog-question.svg</file> + <file>dialog-warning.svg</file> + <file>document-new.svg</file> + <file>document-open-recent.svg</file> + <file>document-open.svg</file> + <file>document-save.svg</file> + <file>edit-clear.svg</file> + <file>edit-copy.svg</file> + <file>edit-cut.svg</file> + <file>edit-delete.svg</file> + <file>edit-find.svg</file> + <file>edit-paste.svg</file> + <file>edit-select-all.svg</file> + <file>face-smile.svg</file> + <file>folder-remote.svg</file> + <file>folder.svg</file> + <file>go-down.svg</file> + <file>go-jump.svg</file> + <file>go-next.svg</file> + <file>go-previous.svg</file> + <file>go-up.svg</file> + <file>help-about.svg</file> + <file>insert-text.svg</file> + <file>list-add.svg</file> + <file>list-remove.svg</file> + <file>media-optical.svg</file> + <file>media-playback-pause.svg</file> + <file>media-playback-start.svg</file> + <file>media-playback-stop.svg</file> + <file>media-playlist-repeat.svg</file> + <file>media-playlist-shuffle.svg</file> + <file>media-record.svg</file> + <file>media-skip-backward.svg</file> + <file>media-skip-forward.svg</file> + <file>multimedia-volume-control.svg</file> + <file>preferences-desktop-font.svg</file> + <file>preferences-system.svg</file> + <file>process-stop.svg</file> + <file>system-run.svg</file> + <file>text-x-generic.svg</file> + <file>user-desktop.svg</file> + <file>user-home.svg</file> + <file>user-trash.svg</file> + <file>view-refresh.svg</file> + <file>view-sort-ascending.svg</file> + <file>view-sort-descending.svg</file> + <file>window-close.svg</file> + </gresource> +</gresources> diff --git a/src/libaudgui/infopopup.cc b/src/libaudgui/infopopup.cc new file mode 100644 index 0000000..8de01c9 --- /dev/null +++ b/src/libaudgui/infopopup.cc @@ -0,0 +1,334 @@ +/* + * infopopup.c + * Copyright 2006-2012 Ariadne Conill, Giacomo Lozito, John Lindgren, and + * Thomas Lange + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gtk/gtk.h> +#include <string.h> + +#define AUD_GLIB_INTEGRATION +#include <libaudcore/audstrings.h> +#include <libaudcore/drct.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/playlist.h> +#include <libaudcore/runtime.h> +#include <libaudcore/tuple.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +static void infopopup_move_to_mouse (GtkWidget * infopopup); + +static const GdkColor gray = {0, 40960, 40960, 40960}; +static const GdkColor white = {0, 65535, 65535, 65535}; + +static struct { + GtkWidget * title_header, * title_label; + GtkWidget * artist_header, * artist_label; + GtkWidget * album_header, * album_label; + GtkWidget * genre_header, * genre_label; + GtkWidget * year_header, * year_label; + GtkWidget * track_header, * track_label; + GtkWidget * length_header, * length_label; + GtkWidget * image; + GtkWidget * progress; +} widgets; + +static String current_file; +static GtkWidget * infopopup_queued; + +/* returns false if album art fetch was queued */ +static bool infopopup_display_image (const char * filename) +{ + bool queued; + AudguiPixbuf pb = audgui_pixbuf_request (filename, & queued); + if (! pb) + return ! queued; + + audgui_pixbuf_scale_within (pb, audgui_get_dpi ()); + gtk_image_set_from_pixbuf ((GtkImage *) widgets.image, pb.get ()); + gtk_widget_show (widgets.image); + + return true; +} + +static void infopopup_art_ready (const char * filename) +{ + if (! infopopup_queued || strcmp (filename, current_file)) + return; + + infopopup_display_image (filename); + audgui_show_unique_window (AUDGUI_INFOPOPUP_WINDOW, infopopup_queued); + infopopup_queued = nullptr; +} + +static void infopopup_progress_cb (void *) +{ + String filename; + int length = 0, time = 0; + + if (aud_drct_get_playing ()) + { + filename = aud_drct_get_filename (); + length = aud_drct_get_length (); + time = aud_drct_get_time (); + } + + if (aud_get_bool ("filepopup_showprogressbar") && filename && + current_file && ! strcmp (filename, current_file) && length > 0) + { + gtk_progress_bar_set_fraction ((GtkProgressBar *) widgets.progress, time / (float) length); + gtk_progress_bar_set_text ((GtkProgressBar *) widgets.progress, str_format_time (time)); + gtk_widget_show (widgets.progress); + } + else + gtk_widget_hide (widgets.progress); +} + +static void infopopup_realized (GtkWidget * widget) +{ + GdkWindow * window = gtk_widget_get_window (widget); + gdk_window_set_back_pixmap (window, nullptr, false); + infopopup_move_to_mouse (widget); +} + +static gboolean infopopup_draw_bg (GtkWidget * widget) +{ + GtkAllocation alloc; + gtk_widget_get_allocation (widget, & alloc); + + cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget)); + auto & c = (gtk_widget_get_style (widget))->base[GTK_STATE_NORMAL]; + cairo_pattern_t * gradient = audgui_dark_bg_gradient (c, alloc.height); + + cairo_set_source (cr, gradient); + cairo_rectangle (cr, 0, 0, alloc.width, alloc.height); + cairo_fill (cr); + + cairo_pattern_destroy (gradient); + cairo_destroy (cr); + return false; +} + +static void infopopup_add_category (GtkWidget * grid, int position, + const char * text, GtkWidget * * header, GtkWidget * * label) +{ + * header = gtk_label_new (nullptr); + * label = gtk_label_new (nullptr); + + gtk_misc_set_alignment ((GtkMisc *) * header, 1, 0.5); + gtk_misc_set_alignment ((GtkMisc *) * label, 0, 0.5); + + gtk_widget_modify_fg (* header, GTK_STATE_NORMAL, & gray); + gtk_widget_modify_fg (* label, GTK_STATE_NORMAL, & white); + + CharPtr markup (g_markup_printf_escaped ("<span style=\"italic\">%s</span>", text)); + gtk_label_set_markup ((GtkLabel *) * header, markup); + + gtk_table_attach ((GtkTable *) grid, * header, 0, 1, position, position + 1, + GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach ((GtkTable *) grid, * label, 1, 2, position, position + 1, + GTK_FILL, GTK_FILL, 0, 0); + + gtk_widget_set_no_show_all (* header, true); + gtk_widget_set_no_show_all (* label, true); +} + +static void infopopup_destroyed () +{ + hook_dissociate ("art ready", (HookFunction) infopopup_art_ready); + + timer_remove (TimerRate::Hz4, infopopup_progress_cb); + + memset (& widgets, 0, sizeof widgets); + + current_file = String (); + infopopup_queued = nullptr; +} + +static GtkWidget * infopopup_create () +{ + int dpi = audgui_get_dpi (); + + GtkWidget * infopopup = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_type_hint ((GtkWindow *) infopopup, GDK_WINDOW_TYPE_HINT_TOOLTIP); + gtk_window_set_decorated ((GtkWindow *) infopopup, false); + gtk_container_set_border_width ((GtkContainer *) infopopup, 4); + + GtkWidget * hbox = gtk_hbox_new (false, 6); + gtk_container_add ((GtkContainer *) infopopup, hbox); + + widgets.image = gtk_image_new (); + gtk_widget_set_size_request (widgets.image, dpi, dpi); + gtk_box_pack_start ((GtkBox *) hbox, widgets.image, false, false, 0); + gtk_widget_set_no_show_all (widgets.image, true); + + GtkWidget * grid = gtk_table_new (0, 0, false); + gtk_table_set_col_spacings ((GtkTable *) grid, 6); + gtk_box_pack_start ((GtkBox *) hbox, grid, true, true, 0); + + infopopup_add_category (grid, 0, _("Title"), & widgets.title_header, & widgets.title_label); + infopopup_add_category (grid, 1, _("Artist"), & widgets.artist_header, & widgets.artist_label); + infopopup_add_category (grid, 2, _("Album"), & widgets.album_header, & widgets.album_label); + infopopup_add_category (grid, 3, _("Genre"), & widgets.genre_header, & widgets.genre_label); + infopopup_add_category (grid, 4, _("Year"), & widgets.year_header, & widgets.year_label); + infopopup_add_category (grid, 5, _("Track"), & widgets.track_header, & widgets.track_label); + infopopup_add_category (grid, 6, _("Length"), & widgets.length_header, & widgets.length_label); + + /* track progress */ + widgets.progress = gtk_progress_bar_new (); + gtk_progress_bar_set_text ((GtkProgressBar *) widgets.progress, ""); + gtk_table_set_row_spacing ((GtkTable *) grid, 6, 4); + gtk_table_attach ((GtkTable *) grid, widgets.progress, 0, 2, 7, 8, + GTK_FILL, GTK_FILL, 0, 0); + + /* do not show the track progress */ + gtk_widget_set_no_show_all (widgets.progress, true); + + /* override background drawing */ + gtk_widget_set_app_paintable (infopopup, true); + + g_signal_connect (infopopup, "realize", (GCallback) infopopup_realized, nullptr); + g_signal_connect (infopopup, "expose-event", (GCallback) infopopup_draw_bg, nullptr); + + return infopopup; +} + +static void infopopup_set_field (GtkWidget * header, GtkWidget * label, const char * text) +{ + if (text) + { + gtk_label_set_text ((GtkLabel *) label, text); + gtk_widget_show (header); + gtk_widget_show (label); + } + else + { + gtk_widget_hide (header); + gtk_widget_hide (label); + } +} + +static void infopopup_set_fields (const Tuple & tuple) +{ + String title = tuple.get_str (Tuple::Title); + String artist = tuple.get_str (Tuple::Artist); + String album = tuple.get_str (Tuple::Album); + String genre = tuple.get_str (Tuple::Genre); + + infopopup_set_field (widgets.title_header, widgets.title_label, title); + infopopup_set_field (widgets.artist_header, widgets.artist_label, artist); + infopopup_set_field (widgets.album_header, widgets.album_label, album); + infopopup_set_field (widgets.genre_header, widgets.genre_label, genre); + + int value = tuple.get_int (Tuple::Length); + infopopup_set_field (widgets.length_header, widgets.length_label, + (value > 0) ? (const char *) str_format_time (value) : nullptr); + + value = tuple.get_int (Tuple::Year); + infopopup_set_field (widgets.year_header, widgets.year_label, + (value > 0) ? (const char *) int_to_str (value) : nullptr); + + value = tuple.get_int (Tuple::Track); + infopopup_set_field (widgets.track_header, widgets.track_label, + (value > 0) ? (const char *) int_to_str (value) : nullptr); +} + +static void infopopup_move_to_mouse (GtkWidget * infopopup) +{ + GdkScreen * screen = gtk_widget_get_screen (infopopup); + GdkRectangle geom; + int x, y, h, w; + + audgui_get_mouse_coords (screen, & x, & y); + audgui_get_monitor_geometry (screen, x, y, & geom); + gtk_window_get_size ((GtkWindow *) infopopup, & w, & h); + + /* If we show the popup right under the cursor, the underlying window gets + * a "leave-notify-event" and immediately hides the popup again. So, we + * offset the popup slightly. */ + if (x + w > geom.x + geom.width) + x -= w + 3; + else + x += 3; + + if (y + h > geom.y + geom.height) + y -= h + 3; + else + y += 3; + + gtk_window_move ((GtkWindow *) infopopup, x, y); +} + +static void infopopup_show (const char * filename, const Tuple & tuple) +{ + audgui_infopopup_hide (); + + current_file = String (filename); + + GtkWidget * infopopup = infopopup_create (); + infopopup_set_fields (tuple); + + hook_associate ("art ready", (HookFunction) infopopup_art_ready, nullptr); + + g_signal_connect (infopopup, "destroy", (GCallback) infopopup_destroyed, nullptr); + + /* start a timer that updates a progress bar if the tooltip + is shown for the song that is being currently played */ + timer_add (TimerRate::Hz4, infopopup_progress_cb); + + /* immediately run the callback once to update progressbar status */ + infopopup_progress_cb (nullptr); + + if (infopopup_display_image (filename)) + audgui_show_unique_window (AUDGUI_INFOPOPUP_WINDOW, infopopup); + else + infopopup_queued = infopopup; +} + +EXPORT void audgui_infopopup_show (Playlist playlist, int entry) +{ + String filename = playlist.entry_filename (entry); + Tuple tuple = playlist.entry_tuple (entry); + + if (filename && tuple.valid ()) + infopopup_show (filename, tuple); +} + +EXPORT void audgui_infopopup_show_current () +{ + auto playlist = Playlist::playing_playlist (); + if (playlist == Playlist ()) + playlist = Playlist::active_playlist (); + + int position = playlist.get_position (); + if (position < 0) + return; + + audgui_infopopup_show (playlist, position); +} + +EXPORT void audgui_infopopup_hide () +{ + audgui_hide_unique_window (AUDGUI_INFOPOPUP_WINDOW); + + if (infopopup_queued) + gtk_widget_destroy (infopopup_queued); +} diff --git a/src/libaudgui/infowin.cc b/src/libaudgui/infowin.cc new file mode 100644 index 0000000..63bb3fa --- /dev/null +++ b/src/libaudgui/infowin.cc @@ -0,0 +1,529 @@ +/* + * infowin.c + * Copyright 2006-2013 Ariadne Conill, Tomasz Moń, Eugene Zagidullin, + * John Lindgren, and Thomas Lange + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gtk/gtk.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/interface.h> +#include <libaudcore/mainloop.h> +#include <libaudcore/playlist.h> +#include <libaudcore/probe.h> +#include <libaudcore/runtime.h> +#include <libaudcore/tuple.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +#define AUDGUI_STATUS_TIMEOUT 3000 + +enum { + CODEC_FORMAT, + CODEC_QUALITY, + CODEC_BITRATE, + CODEC_ITEMS +}; + +static const char * codec_labels[CODEC_ITEMS] = { + N_("Format:"), + N_("Quality:"), + N_("Bitrate:") +}; + +static struct { + GtkWidget * location; + GtkWidget * title; + GtkWidget * artist; + GtkWidget * album; + GtkWidget * album_artist; + GtkWidget * comment; + GtkWidget * year; + GtkWidget * track; + GtkWidget * genre; + GtkWidget * image; + GtkWidget * codec[3]; + GtkWidget * apply; + GtkWidget * autofill; + GtkWidget * ministatus; +} widgets; + +static GtkWidget * infowin; +static Playlist current_playlist; +static int current_entry; +static String current_file; +static Tuple current_tuple; +static PluginHandle * current_decoder = nullptr; +static bool can_write = false; +static QueuedFunc ministatus_timer; + +/* This is by no means intended to be a complete list. If it is not short, it + * is useless: scrolling through ten pages of dropdown list is more work than + * typing out the genre. */ + +static const char * genre_table[] = { + N_("Acid Jazz"), + N_("Acid Rock"), + N_("Ambient"), + N_("Bebop"), + N_("Bluegrass"), + N_("Blues"), + N_("Chamber Music"), + N_("Classical"), + N_("Country"), + N_("Death Metal"), + N_("Disco"), + N_("Easy Listening"), + N_("Folk"), + N_("Funk"), + N_("Gangsta Rap"), + N_("Gospel"), + N_("Grunge"), + N_("Hard Rock"), + N_("Heavy Metal"), + N_("Hip-hop"), + N_("House"), + N_("Jazz"), + N_("Jungle"), + N_("Metal"), + N_("New Age"), + N_("New Wave"), + N_("Noise"), + N_("Pop"), + N_("Punk Rock"), + N_("Rap"), + N_("Reggae"), + N_("Rock"), + N_("Rock and Roll"), + N_("Rhythm and Blues"), + N_("Ska"), + N_("Soul"), + N_("Swing"), + N_("Techno"), + N_("Trip-hop")}; + +static GtkWidget * small_label_new (const char * text) +{ + static PangoAttrList * attrs = nullptr; + + if (! attrs) + { + attrs = pango_attr_list_new (); + pango_attr_list_insert (attrs, pango_attr_scale_new (PANGO_SCALE_SMALL)); + } + + GtkWidget * label = gtk_label_new (text); + gtk_label_set_attributes ((GtkLabel *) label, attrs); + gtk_misc_set_alignment ((GtkMisc *) label, 0, 0.5); + + return label; +} + +static void set_entry_str_from_field (GtkWidget * widget, const Tuple & tuple, + Tuple::Field field, bool editable, bool clear, bool & changed) +{ + String text = tuple.get_str (field); + + if (! text && ! clear) + { + if (gtk_entry_get_text_length ((GtkEntry *) widget) > 0) + changed = true; + return; + } + + gtk_entry_set_text ((GtkEntry *) widget, text ? text : ""); + gtk_editable_set_editable ((GtkEditable *) widget, editable); +} + +static void set_entry_int_from_field (GtkWidget * widget, const Tuple & tuple, + Tuple::Field field, bool editable, bool clear, bool & changed) +{ + int value = tuple.get_int (field); + + if (value <= 0 && ! clear) + { + if (gtk_entry_get_text_length ((GtkEntry *) widget) > 0) + changed = true; + return; + } + + gtk_entry_set_text ((GtkEntry *) widget, (value > 0) ? (const char *) int_to_str (value) : ""); + gtk_editable_set_editable ((GtkEditable *) widget, editable); +} + +static void set_field_str_from_entry (Tuple & tuple, Tuple::Field field, GtkWidget * widget) +{ + const char * text = gtk_entry_get_text ((GtkEntry *) widget); + + if (text[0]) + tuple.set_str (field, text); + else + tuple.unset (field); +} + +static void set_field_int_from_entry (Tuple & tuple, Tuple::Field field, GtkWidget * widget) +{ + const char * text = gtk_entry_get_text ((GtkEntry *) widget); + + if (text[0]) + tuple.set_int (field, atoi (text)); + else + tuple.unset (field); +} + +static void entry_changed () +{ + if (can_write) + gtk_widget_set_sensitive (widgets.apply, true); +} + +static void ministatus_display_message (const char * text) +{ + gtk_label_set_text ((GtkLabel *) widgets.ministatus, text); + gtk_widget_hide (widgets.autofill); + gtk_widget_show (widgets.ministatus); + + ministatus_timer.queue (AUDGUI_STATUS_TIMEOUT, [] (void *) { + gtk_widget_hide (widgets.ministatus); + gtk_widget_show (widgets.autofill); + }, nullptr); +} + +static void infowin_update_tuple () +{ + set_field_str_from_entry (current_tuple, Tuple::Title, widgets.title); + set_field_str_from_entry (current_tuple, Tuple::Artist, widgets.artist); + set_field_str_from_entry (current_tuple, Tuple::Album, widgets.album); + set_field_str_from_entry (current_tuple, Tuple::AlbumArtist, widgets.album_artist); + set_field_str_from_entry (current_tuple, Tuple::Comment, widgets.comment); + set_field_str_from_entry (current_tuple, Tuple::Genre, + gtk_bin_get_child ((GtkBin *) widgets.genre)); + set_field_int_from_entry (current_tuple, Tuple::Year, widgets.year); + set_field_int_from_entry (current_tuple, Tuple::Track, widgets.track); + + if (aud_file_write_tuple (current_file, current_decoder, current_tuple)) + { + ministatus_display_message (_("Save successful")); + gtk_widget_set_sensitive (widgets.apply, false); + } + else + ministatus_display_message (_("Save error")); +} + +static void infowin_select_entry (int entry) +{ + if (entry >= 0 && entry < current_playlist.n_entries ()) + { + current_playlist.select_all (false); + current_playlist.select_entry (entry, true); + current_playlist.set_focus (entry); + audgui_infowin_show (current_playlist, entry); + } + else + audgui_infowin_hide (); +} + +static void infowin_prev () +{ + infowin_select_entry (current_entry - 1); +} + +static void infowin_next () +{ + infowin_select_entry (current_entry + 1); +} + +static void genre_fill (GtkWidget * combo) +{ + GList * list = nullptr; + GList * node; + + for (const char * genre : genre_table) + list = g_list_prepend (list, _(genre)); + + list = g_list_sort (list, (GCompareFunc) strcmp); + + for (node = list; node != nullptr; node = node->next) + gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, (const char *) node->data); + + g_list_free (list); +} + +static void autofill_toggled (GtkToggleButton * toggle) +{ + aud_set_bool ("audgui", "clear_song_fields", ! gtk_toggle_button_get_active (toggle)); +} + +static void infowin_display_image (const char * filename) +{ + if (! current_file || strcmp (filename, current_file)) + return; + + AudguiPixbuf pb = audgui_pixbuf_request (filename); + if (! pb) + pb = audgui_pixbuf_fallback (); + + if (pb) + audgui_scaled_image_set (widgets.image, pb.get ()); +} + +static void infowin_destroyed () +{ + hook_dissociate ("art ready", (HookFunction) infowin_display_image); + + ministatus_timer.stop (); + + memset (& widgets, 0, sizeof widgets); + + infowin = nullptr; + current_file = String (); + current_tuple = Tuple (); + current_decoder = nullptr; +} + +static void add_entry (GtkWidget * grid, const char * title, GtkWidget * entry, + int x, int y, int span) +{ + GtkWidget * label = small_label_new (title); + + gtk_table_attach ((GtkTable *) grid, label, x, x + span, y, y + 1, + GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach ((GtkTable *) grid, entry, x, x + span, y + 1, y + 2, + GTK_FILL, GTK_FILL, 0, 0); + + g_signal_connect (entry, "changed", (GCallback) entry_changed, nullptr); +} + +static void create_infowin () +{ + int dpi = audgui_get_dpi (); + + infowin = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_container_set_border_width ((GtkContainer *) infowin, 6); + gtk_window_set_title ((GtkWindow *) infowin, _("Song Info")); + gtk_window_set_type_hint ((GtkWindow *) infowin, + GDK_WINDOW_TYPE_HINT_DIALOG); + + GtkWidget * main_grid = gtk_table_new (0, 0, false); + gtk_table_set_col_spacings ((GtkTable *) main_grid, 6); + gtk_table_set_row_spacings ((GtkTable *) main_grid, 6); + gtk_container_add ((GtkContainer *) infowin, main_grid); + + widgets.image = audgui_scaled_image_new (nullptr); + gtk_table_attach_defaults ((GtkTable *) main_grid, widgets.image, 0, 1, 0, 1); + + widgets.location = gtk_label_new (""); + gtk_widget_set_size_request (widgets.location, 2 * dpi, -1); + gtk_label_set_line_wrap ((GtkLabel *) widgets.location, true); + gtk_label_set_line_wrap_mode ((GtkLabel *) widgets.location, PANGO_WRAP_WORD_CHAR); + gtk_label_set_selectable ((GtkLabel *) widgets.location, true); + gtk_table_attach ((GtkTable *) main_grid, widgets.location, 0, 1, 1, 2, + GTK_FILL, GTK_FILL, 0, 0); + + GtkWidget * codec_grid = gtk_table_new (0, 0, false); + gtk_table_set_row_spacings ((GtkTable *) codec_grid, 2); + gtk_table_set_col_spacings ((GtkTable *) codec_grid, 12); + gtk_table_attach ((GtkTable *) main_grid, codec_grid, 0, 1, 2, 3, + GTK_FILL, GTK_FILL, 0, 0); + + for (int row = 0; row < CODEC_ITEMS; row ++) + { + GtkWidget * label = small_label_new (_(codec_labels[row])); + gtk_table_attach ((GtkTable *) codec_grid, label, 0, 1, row, row + 1, + GTK_FILL, GTK_FILL, 0, 0); + + widgets.codec[row] = small_label_new (nullptr); + gtk_table_attach ((GtkTable *) codec_grid, widgets.codec[row], 1, 2, row, row + 1, + GTK_FILL, GTK_FILL, 0, 0); + } + + GtkWidget * grid = gtk_table_new (0, 0, false); + gtk_table_set_row_spacings ((GtkTable *) grid, 2); + gtk_table_set_col_spacings ((GtkTable *) grid, 6); + gtk_table_attach ((GtkTable *) main_grid, grid, 1, 2, 0, 3, + GTK_FILL, GTK_FILL, 0, 0); + + widgets.title = gtk_entry_new (); + gtk_widget_set_size_request (widgets.title, 3 * dpi, -1); + add_entry (grid, _("Title"), widgets.title, 0, 0, 2); + + widgets.artist = gtk_entry_new (); + add_entry (grid, _("Artist"), widgets.artist, 0, 2, 2); + + widgets.album = gtk_entry_new (); + add_entry (grid, _("Album"), widgets.album, 0, 4, 2); + + widgets.album_artist = gtk_entry_new (); + add_entry (grid, _("Album Artist"), widgets.album_artist, 0, 6, 2); + + widgets.comment = gtk_entry_new (); + add_entry (grid, _("Comment"), widgets.comment, 0, 8, 2); + + widgets.genre = gtk_combo_box_text_new_with_entry (); + genre_fill (widgets.genre); + add_entry (grid, _("Genre"), widgets.genre, 0, 10, 2); + + widgets.year = gtk_entry_new (); + add_entry (grid, _("Year"), widgets.year, 0, 12, 1); + + widgets.track = gtk_entry_new (); + add_entry (grid, _("Track Number"), widgets.track, 1, 12, 1); + + GtkWidget * bottom_hbox = gtk_hbox_new (false, 6); + gtk_table_attach ((GtkTable *) main_grid, bottom_hbox, 0, 2, 3, 4, + GTK_FILL, GTK_FILL, 0, 0); + + widgets.autofill = gtk_check_button_new_with_mnemonic (_("_Auto-fill empty fields")); + + gtk_toggle_button_set_active ((GtkToggleButton *) widgets.autofill, + ! aud_get_bool ("audgui", "clear_song_fields")); + g_signal_connect (widgets.autofill, "toggled", (GCallback) autofill_toggled, nullptr); + + gtk_widget_set_no_show_all (widgets.autofill, true); + gtk_widget_show (widgets.autofill); + gtk_box_pack_start ((GtkBox *) bottom_hbox, widgets.autofill, false, false, 0); + + widgets.ministatus = small_label_new (nullptr); + gtk_widget_set_no_show_all (widgets.ministatus, true); + gtk_box_pack_start ((GtkBox *) bottom_hbox, widgets.ministatus, true, true, 0); + + widgets.apply = audgui_button_new (_("_Save"), "document-save", + (AudguiCallback) infowin_update_tuple, nullptr); + + GtkWidget * close_button = audgui_button_new (_("_Close"), "window-close", + (AudguiCallback) audgui_infowin_hide, nullptr); + + GtkWidget * prev_button = audgui_button_new (_("_Previous"), "go-previous", + (AudguiCallback) infowin_prev, nullptr); + + GtkWidget * next_button = audgui_button_new (_("_Next"), "go-next", + (AudguiCallback) infowin_next, nullptr); + + gtk_box_pack_end ((GtkBox *) bottom_hbox, close_button, false, false, 0); + gtk_box_pack_end ((GtkBox *) bottom_hbox, widgets.apply, false, false, 0); + gtk_box_pack_end ((GtkBox *) bottom_hbox, next_button, false, false, 0); + gtk_box_pack_end ((GtkBox *) bottom_hbox, prev_button, false, false, 0); + + audgui_destroy_on_escape (infowin); + g_signal_connect (infowin, "destroy", (GCallback) infowin_destroyed, nullptr); + + hook_associate ("art ready", (HookFunction) infowin_display_image, nullptr); +} + +static void infowin_show (Playlist list, int entry, const String & filename, + const Tuple & tuple, PluginHandle * decoder, bool writable) +{ + if (! infowin) + create_infowin (); + + current_playlist = list; + current_entry = entry; + current_file = filename; + current_tuple = tuple.ref (); + current_decoder = decoder; + can_write = writable; + + bool clear = aud_get_bool ("audgui", "clear_song_fields"); + bool changed = false; + + set_entry_str_from_field (widgets.title, tuple, Tuple::Title, writable, clear, changed); + set_entry_str_from_field (widgets.artist, tuple, Tuple::Artist, writable, clear, changed); + set_entry_str_from_field (widgets.album, tuple, Tuple::Album, writable, clear, changed); + set_entry_str_from_field (widgets.album_artist, tuple, Tuple::AlbumArtist, writable, clear, changed); + set_entry_str_from_field (widgets.comment, tuple, Tuple::Comment, writable, clear, changed); + set_entry_str_from_field (gtk_bin_get_child ((GtkBin *) widgets.genre), + tuple, Tuple::Genre, writable, clear, changed); + + gtk_label_set_text ((GtkLabel *) widgets.location, uri_to_display (filename)); + + set_entry_int_from_field (widgets.year, tuple, Tuple::Year, writable, clear, changed); + set_entry_int_from_field (widgets.track, tuple, Tuple::Track, writable, clear, changed); + + String codec_values[CODEC_ITEMS]; + + codec_values[CODEC_FORMAT] = tuple.get_str (Tuple::Codec); + codec_values[CODEC_QUALITY] = tuple.get_str (Tuple::Quality); + + if (tuple.get_value_type (Tuple::Bitrate) == Tuple::Int) + codec_values[CODEC_BITRATE] = String (str_printf (_("%d kb/s"), + tuple.get_int (Tuple::Bitrate))); + + for (int row = 0; row < CODEC_ITEMS; row ++) + { + const char * text = codec_values[row] ? (const char *) codec_values[row] : _("N/A"); + gtk_label_set_text ((GtkLabel *) widgets.codec[row], text); + } + + infowin_display_image (filename); + + gtk_widget_set_sensitive (widgets.apply, changed); + gtk_widget_grab_focus (widgets.title); + + if (! audgui_reshow_unique_window (AUDGUI_INFO_WINDOW)) + audgui_show_unique_window (AUDGUI_INFO_WINDOW, infowin); +} + +EXPORT void audgui_infowin_show (Playlist playlist, int entry) +{ + String filename = playlist.entry_filename (entry); + g_return_if_fail (filename != nullptr); + + String error; + PluginHandle * decoder = playlist.entry_decoder (entry, Playlist::Wait, & error); + Tuple tuple = decoder ? playlist.entry_tuple (entry, Playlist::Wait, & error) : Tuple (); + + if (decoder && tuple.valid () && ! aud_custom_infowin (filename, decoder)) + { + /* cuesheet entries cannot be updated */ + bool can_write = aud_file_can_write_tuple (filename, decoder) && + ! tuple.is_set (Tuple::StartTime); + + tuple.delete_fallbacks (); + infowin_show (playlist, entry, filename, tuple, decoder, can_write); + } + else + audgui_infowin_hide (); + + if (error) + aud_ui_show_error (str_printf (_("Error opening %s:\n%s"), + (const char *) filename, (const char *) error)); +} + +EXPORT void audgui_infowin_show_current () +{ + auto playlist = Playlist::playing_playlist (); + if (playlist == Playlist ()) + playlist = Playlist::active_playlist (); + + int position = playlist.get_position (); + if (position < 0) + return; + + audgui_infowin_show (playlist, position); +} + +EXPORT void audgui_infowin_hide () +{ + audgui_hide_unique_window (AUDGUI_INFO_WINDOW); +} diff --git a/src/libaudgui/init.cc b/src/libaudgui/init.cc new file mode 100644 index 0000000..36ad24d --- /dev/null +++ b/src/libaudgui/init.cc @@ -0,0 +1,387 @@ +/* + * init.c + * Copyright 2010-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <assert.h> +#include <stdlib.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/hook.h> +#include <libaudcore/playlist.h> +#include <libaudcore/plugins.h> +#include <libaudcore/runtime.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +extern "C" { +#include "images.h" +} + +static const char * const audgui_defaults[] = { + "clear_song_fields", "TRUE", + "close_dialog_add", "FALSE", + "close_dialog_open", "TRUE", + "close_jtf_dialog", "TRUE", + "record", "FALSE", + "remember_jtf_entry", "TRUE", + nullptr +}; + +static const char * const window_names[AUDGUI_NUM_UNIQUE_WINDOWS] = { + "about_win", + "equalizer_win", + "eq_preset_win", + "filebrowser_win", + nullptr, /* infopopup position is not saved */ + "info_win", + "jump_to_time_win", + "jump_to_track_win", + "playlist_export_win", + "playlist_import_win", + "preset_browser_win", + "queue_manager_win", + "url_opener_win" +}; + +static int init_count = 0; + +static GtkWidget * windows[AUDGUI_NUM_UNIQUE_WINDOWS]; + +static gboolean configure_cb (GtkWidget * window, GdkEventConfigure * event, const char * name) +{ + if (gtk_widget_get_visible (window)) + { + int pos[4]; + gtk_window_get_position ((GtkWindow *) window, & pos[0], & pos[1]); + gtk_window_get_size ((GtkWindow *) window, & pos[2], & pos[3]); + + pos[2] = audgui_to_portable_dpi (pos[2]); + pos[3] = audgui_to_portable_dpi (pos[3]); + + aud_set_str ("audgui", name, int_array_to_str (pos, 4)); + } + + return false; +} + +void audgui_show_unique_window (int id, GtkWidget * widget) +{ + g_return_if_fail (id >= 0 && id < AUDGUI_NUM_UNIQUE_WINDOWS); + + if (windows[id]) + gtk_widget_destroy (windows[id]); + + windows[id] = widget; + g_signal_connect (widget, "destroy", (GCallback) gtk_widget_destroyed, & windows[id]); + + if (window_names[id]) + { + String str = aud_get_str ("audgui", window_names[id]); + int pos[4]; + + if (str_to_int_array (str, pos, 4)) + { + pos[2] = audgui_to_native_dpi (pos[2]); + pos[3] = audgui_to_native_dpi (pos[3]); + + gtk_window_move ((GtkWindow *) widget, pos[0], pos[1]); + gtk_window_set_default_size ((GtkWindow *) widget, pos[2], pos[3]); + } + + g_signal_connect (widget, "configure-event", (GCallback) configure_cb, + (void *) window_names[id]); + } + + gtk_widget_show_all (widget); +} + +bool audgui_reshow_unique_window (int id) +{ + g_return_val_if_fail (id >= 0 && id < AUDGUI_NUM_UNIQUE_WINDOWS, false); + + if (! windows[id]) + return false; + + gtk_window_present ((GtkWindow *) windows[id]); + return true; +} + +void audgui_hide_unique_window (int id) +{ + g_return_if_fail (id >= 0 && id < AUDGUI_NUM_UNIQUE_WINDOWS); + + if (windows[id]) + gtk_widget_destroy (windows[id]); +} + +#ifdef _WIN32 +/* On Windows, the default icon sizes are fixed. + * Adjust them for varying screen resolutions. */ +void adjust_icon_sizes (void) +{ + struct Mapping { + GtkIconSize size; + const char * name; + }; + + static const Mapping mappings[] = { + {GTK_ICON_SIZE_MENU, "gtk-menu"}, + {GTK_ICON_SIZE_SMALL_TOOLBAR, "gtk-small-toolbar"}, + {GTK_ICON_SIZE_LARGE_TOOLBAR, "gtk-large-toolbar"}, + {GTK_ICON_SIZE_BUTTON, "gtk-button"}, + {GTK_ICON_SIZE_DND, "gtk-dnd"}, + {GTK_ICON_SIZE_DIALOG, "gtk-dialog"} + }; + + StringBuf value; + + for (auto & m : mappings) + { + int width, height; + if (gtk_icon_size_lookup (m.size, & width, & height)) + { + width = audgui_to_native_dpi (width); + height = audgui_to_native_dpi (height); + + const char * sep = value.len () ? ":" : ""; + str_append_printf (value, "%s%s=%d,%d", sep, m.name, width, height); + } + } + + GtkSettings * settings = gtk_settings_get_default (); + g_object_set ((GObject *) settings, "gtk-icon-sizes", (const char *) value, nullptr); +} +#endif + +static int get_icon_size (GtkIconSize size) +{ + int width, height; + if (gtk_icon_size_lookup (size, & width, & height)) + return (width + height) / 2; + + return audgui_to_native_dpi (16); +} + +static void load_fallback_icon (const char * icon, int size) +{ + StringBuf resource = str_concat ({"/org/audacious/", icon, ".svg"}); + auto pixbuf = gdk_pixbuf_new_from_resource_at_scale (resource, size, size, true, nullptr); + + if (pixbuf) + { + gtk_icon_theme_add_builtin_icon (icon, size, pixbuf); + g_object_unref (pixbuf); + } +} + +static void load_fallback_icons () +{ + static const char * const all_icons[] = { + "application-exit", + "applications-graphics", + "applications-internet", + "applications-system", + "appointment-new", + "audacious", + "audio-card", + "audio-volume-high", + "audio-volume-low", + "audio-volume-medium", + "audio-volume-muted", + "audio-x-generic", + "dialog-error", + "dialog-information", + "dialog-question", + "dialog-warning", + "document-new", + "document-open-recent", + "document-open", + "document-save", + "edit-clear", + "edit-copy", + "edit-cut", + "edit-delete", + "edit-find", + "edit-paste", + "edit-select-all", + "face-smile", + "folder-remote", + "folder", + "go-down", + "go-jump", + "go-next", + "go-previous", + "go-up", + "help-about", + "insert-text", + "list-add", + "list-remove", + "media-optical", + "media-playback-pause", + "media-playback-start", + "media-playback-stop", + "media-playlist-repeat", + "media-playlist-shuffle", + "media-record", + "media-skip-backward", + "media-skip-forward", + "multimedia-volume-control", + "preferences-system", + "process-stop", + "system-run", + "text-x-generic", + "user-desktop", + "user-home", + "user-trash", + "view-refresh", + "view-sort-ascending", + "view-sort-descending", + "window-close" + }; + + static const char * const toolbar_icons[] = { + "audacious", + "audio-volume-high", + "audio-volume-low", + "audio-volume-medium", + "audio-volume-muted", + "document-open", + "edit-find", + "list-add", + "media-playback-pause", + "media-playback-start", + "media-playback-stop", + "media-playlist-repeat", + "media-playlist-shuffle", + "media-record", + "media-skip-backward", + "media-skip-forward" + }; + + static const char * const dialog_icons[] = { + "dialog-error", + "dialog-information", + "dialog-question", + "dialog-warning" + }; + + /* keep this in sync with the list in prefs-window.cc */ + static const char * const category_icons[] = { + "applications-graphics", + "applications-internet", + "applications-system", + "audacious", /* for window icons */ + "audio-volume-medium", + "audio-x-generic", /* also used for fallback album art */ + "dialog-information", + "preferences-system" + }; + + g_resources_register (images_get_resource ()); + +#ifdef _WIN32 + adjust_icon_sizes (); +#endif + + int menu_size = get_icon_size (GTK_ICON_SIZE_MENU); + for (const char * icon : all_icons) + load_fallback_icon (icon, menu_size); + + GtkIconSize icon_size; + GtkSettings * settings = gtk_settings_get_default (); + g_object_get (settings, "gtk-toolbar-icon-size", & icon_size, NULL); + + int toolbar_size = get_icon_size (icon_size); + for (const char * icon : toolbar_icons) + load_fallback_icon (icon, toolbar_size); + + int dialog_size = get_icon_size (GTK_ICON_SIZE_DIALOG); + for (const char * icon : dialog_icons) + load_fallback_icon (icon, dialog_size); + + int category_size = audgui_to_native_dpi (48); + for (const char * icon : category_icons) + load_fallback_icon (icon, category_size); +} + +static void playlist_set_playing_cb (void *, void *) +{ + audgui_pixbuf_uncache (); +} + +static void playlist_position_cb (void * list, void *) +{ + if (aud::from_ptr<Playlist> (list) == Playlist::playing_playlist ()) + audgui_pixbuf_uncache (); +} + +EXPORT void audgui_init () +{ + static bool icons_loaded = false; + assert (aud_get_mainloop_type () == MainloopType::GLib); + + if (init_count ++) + return; + + static char app_name[] = "audacious"; + static char * app_args[] = {app_name, nullptr}; + + int dummy_argc = 1; + char * * dummy_argv = app_args; + + gtk_init (& dummy_argc, & dummy_argv); + + if (! icons_loaded) + { + load_fallback_icons (); + icons_loaded = true; + } + + aud_config_set_defaults ("audgui", audgui_defaults); + + status_init (); + + hook_associate ("playlist set playing", playlist_set_playing_cb, nullptr); + hook_associate ("playlist position", playlist_position_cb, nullptr); + +#ifndef _WIN32 + gtk_window_set_default_icon_name ("audacious"); +#endif +} + +EXPORT void audgui_cleanup () +{ + if (-- init_count) + return; + + hook_dissociate ("playlist set playing", playlist_set_playing_cb); + hook_dissociate ("playlist position", playlist_position_cb); + + status_cleanup (); + + for (int id = 0; id < AUDGUI_NUM_UNIQUE_WINDOWS; id ++) + audgui_hide_unique_window (id); + + audgui_hide_prefs_window (); + audgui_infopopup_hide (); + + plugin_menu_cleanup (); + plugin_prefs_cleanup (); +} diff --git a/src/libaudgui/internal.h b/src/libaudgui/internal.h new file mode 100644 index 0000000..b43c97c --- /dev/null +++ b/src/libaudgui/internal.h @@ -0,0 +1,64 @@ +/* + * internal.h + * Copyright 2010-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef AUDGUI_INTERNAL_H +#define AUDGUI_INTERNAL_H + +#include <gtk/gtk.h> + +enum class PluginType; + +enum { + AUDGUI_ABOUT_WINDOW, + AUDGUI_EQ_PRESET_WINDOW, + AUDGUI_EQUALIZER_WINDOW, + AUDGUI_FILEBROWSER_WINDOW, + AUDGUI_INFOPOPUP_WINDOW, + AUDGUI_INFO_WINDOW, + AUDGUI_JUMP_TO_TIME_WINDOW, + AUDGUI_JUMP_TO_TRACK_WINDOW, + AUDGUI_PLAYLIST_EXPORT_WINDOW, + AUDGUI_PLAYLIST_IMPORT_WINDOW, + AUDGUI_PRESET_BROWSER_WINDOW, + AUDGUI_QUEUE_MANAGER_WINDOW, + AUDGUI_URL_OPENER_WINDOW, + AUDGUI_NUM_UNIQUE_WINDOWS +}; + +void audgui_show_unique_window (int id, GtkWidget * widget); +bool audgui_reshow_unique_window (int id); +void audgui_hide_unique_window (int id); + +/* pixbufs.c */ +void audgui_pixbuf_uncache (); + +/* plugin-menu.c */ +void plugin_menu_cleanup (); + +/* plugin-prefs.c */ +void plugin_prefs_cleanup (); + +/* plugin-view.c */ +GtkWidget * plugin_view_new (PluginType type); + +/* status.c */ +void status_init (); +void status_cleanup (); + +#endif /* AUDGUI_INTERNAL_H */ diff --git a/src/libaudgui/jump-to-time.cc b/src/libaudgui/jump-to-time.cc new file mode 100644 index 0000000..bd4925a --- /dev/null +++ b/src/libaudgui/jump-to-time.cc @@ -0,0 +1,62 @@ +/* + * jump-to-time.c + * Copyright 2012-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gtk/gtk.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/drct.h> +#include <libaudcore/i18n.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +static void jump_cb (void * entry) +{ + const char * text = gtk_entry_get_text ((GtkEntry *) entry); + unsigned minutes, seconds; + + if (sscanf (text, "%u:%u", & minutes, & seconds) == 2 && aud_drct_get_playing ()) + aud_drct_seek ((minutes * 60 + seconds) * 1000); +} + +EXPORT void audgui_jump_to_time () +{ + if (audgui_reshow_unique_window (AUDGUI_JUMP_TO_TIME_WINDOW)) + return; + + GtkWidget * entry = gtk_entry_new (); + gtk_entry_set_activates_default ((GtkEntry *) entry, true); + + GtkWidget * button1 = audgui_button_new (_("_Jump"), "go-jump", jump_cb, entry); + GtkWidget * button2 = audgui_button_new (_("_Cancel"), "process-stop", nullptr, nullptr); + + GtkWidget * dialog = audgui_dialog_new (GTK_MESSAGE_OTHER, + _("Jump to Time"), _("Enter time (minutes:seconds):"), button1, button2); + + audgui_dialog_add_widget (dialog, entry); + + if (aud_drct_get_playing ()) + { + int time = aud_drct_get_time () / 1000; + gtk_entry_set_text ((GtkEntry *) entry, str_printf ("%u:%02u", time / 60, time % 60)); + } + + audgui_show_unique_window (AUDGUI_JUMP_TO_TIME_WINDOW, dialog); +} diff --git a/src/libaudgui/jump-to-track-cache.cc b/src/libaudgui/jump-to-track-cache.cc new file mode 100644 index 0000000..754cce1 --- /dev/null +++ b/src/libaudgui/jump-to-track-cache.cc @@ -0,0 +1,214 @@ +/* + * jump-to-track-cache.c + * Copyright 2008-2014 Jussi Judin and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "jump-to-track-cache.h" + +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include <glib.h> /* for GRegex */ + +#include <libaudcore/audstrings.h> +#include <libaudcore/playlist.h> +#include <libaudcore/runtime.h> + +/** + * Creates an regular expression list usable in searches from search keyword. + * + * In searches, every regular expression on this list is matched against + * the search title and if they all match, the title is declared as + * matching one. + * + * Regular expressions in list are formed by splitting the 'keyword' to words + * by splitting the keyword string with space character. + */ +Index<GRegex *> jump_to_track_cache_regex_list_create (const char * keyword) +{ + Index<GRegex *> regex_list; + + /* Chop the key string into ' '-separated key regex-pattern strings */ + Index<String> words = str_list_to_index (keyword, " "); + + /* create a list of regex using the regex-pattern strings */ + for (const char * word : words) + { + // Ignore empty words. + if (! word[0]) + continue; + + GRegex * regex = g_regex_new (word, G_REGEX_CASELESS, (GRegexMatchFlags) 0, nullptr); + if (regex) + regex_list.append (regex); + } + + return regex_list; +} + +/** + * Checks if 'song' matches all regular expressions in 'regex_list'. + */ +static bool jump_to_track_match (const char * name, Index<GRegex *> & regex_list) +{ + if (! name) + return false; + + for (GRegex * regex : regex_list) + { + if (! g_regex_match (regex, name, (GRegexMatchFlags) 0, nullptr)) + return false; + } + + return true; +} + +/** + * Returns all songs that match 'keyword'. + * + * Searches are conducted against entries in 'search_space' variable + * and after the search, search result is added to 'cache'. + * + * @param cache The result of this search is added to cache. + * @param search_space Entries inside which the search is conducted. + * @param keyword Normalized string for searches. + */ +const KeywordMatches * JumpToTrackCache::search_within + (const KeywordMatches * subset, const char * keyword) +{ + Index<GRegex *> regex_list = jump_to_track_cache_regex_list_create (keyword); + + KeywordMatches * k = add (String (keyword), KeywordMatches ()); + + for (const KeywordMatch & item : * subset) + { + if (! regex_list.len () || + jump_to_track_match (item.title, regex_list) || + jump_to_track_match (item.artist, regex_list) || + jump_to_track_match (item.album, regex_list) || + jump_to_track_match (item.path, regex_list)) + k->append (item); + } + + for (GRegex * regex : regex_list) + g_regex_unref (regex); + + return k; +} + +/** + * Creates a new song search cache. + * + * Returned value should be freed with ui_jump_to_track_cache_free() function. + */ +void JumpToTrackCache::init () +{ + auto playlist = Playlist::active_playlist (); + int entries = playlist.n_entries (); + + // the empty string will match all playlist entries + KeywordMatches & k = * add (String (""), KeywordMatches ()); + + k.insert (0, entries); + + for (int entry = 0; entry < entries; entry ++) + { + KeywordMatch & item = k[entry]; + item.entry = entry; + item.path = String (uri_to_display (playlist.entry_filename (entry))); + + Tuple tuple = playlist.entry_tuple (entry, Playlist::NoWait); + item.title = tuple.get_str (Tuple::Title); + item.artist = tuple.get_str (Tuple::Artist); + item.album = tuple.get_str (Tuple::Album); + } +} + +/** + * Searches 'keyword' inside 'playlist' by using 'cache' to speed up searching. + * + * Searches are basically conducted as follows: + * + * Cache is checked if it has the information about right playlist and + * initialized with playlist data if needed. + * + * Keyword is normalized for searching (Unicode NFKD, case folding) + * + * Cache is checked if it has keyword and if it has, we can immediately get + * the search results and return. If not, searching goes as follows: + * + * Search for the longest word that is in cache that matches the beginning + * of keyword and use the cached matches as base for the current search. + * The shortest word that can be matched against is the empty string "", so + * there should always be matches in cache. + * + * After that conduct the search by splitting keyword into words separated + * by space and using regular expressions. + * + * When the keyword is searched, search result is added to cache to + * corresponding keyword that can be used as base for new searches. + * + * The motivation for caching is that to search word 'some cool song' one + * has to type following strings that are all searched individually: + * + * s + * so + * som + * some + * some + * some c + * some co + * some coo + * some cool + * some cool + * some cool s + * some cool so + * some cool son + * some cool song + * + * If the search results are cached in every phase and the result of + * the maximum length matching string is used as base for concurrent + * searches, we can probably get the matches reduced to some hundreds + * after a few letters typed on playlists with thousands of songs and + * reduce useless iteration quite a lot. + * + * Return: GArray of int + */ +const KeywordMatches * JumpToTrackCache::search (const char * keyword) +{ + if (! n_items ()) + init (); + + StringBuf match_string = str_copy (keyword); + const KeywordMatches * matches; + + while (! (matches = lookup (String (match_string)))) + { + // try to reuse the result of a previous search + // (the empty string is always present as a fallback) + assert (match_string[0]); + match_string[strlen (match_string) - 1] = 0; + } + + // exact match? + if (! strcmp (match_string, keyword)) + return matches; + + // search within the previous result + return search_within (matches, keyword); +} diff --git a/src/libaudgui/jump-to-track-cache.h b/src/libaudgui/jump-to-track-cache.h new file mode 100644 index 0000000..d265eb1 --- /dev/null +++ b/src/libaudgui/jump-to-track-cache.h @@ -0,0 +1,46 @@ +/* + * jump-to-track-cache.h + * Copyright 2008 Jussi Judin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDGUI_JUMPTOTRACK_CACHE_H +#define LIBAUDGUI_JUMPTOTRACK_CACHE_H + +#include <libaudcore/index.h> +#include <libaudcore/multihash.h> +#include <libaudcore/objects.h> + +// Struct to keep information about matches from searches. +struct KeywordMatch { + int entry; + String title, artist, album, path; +}; + +typedef Index<KeywordMatch> KeywordMatches; + +class JumpToTrackCache : private SimpleHash<String, KeywordMatches> +{ +public: + const KeywordMatches * search (const char * keyword); + using SimpleHash::clear; + +private: + void init (); + const KeywordMatches * search_within (const KeywordMatches * subset, const char * keyword); +}; + +#endif diff --git a/src/libaudgui/jump-to-track.cc b/src/libaudgui/jump-to-track.cc new file mode 100644 index 0000000..b6db4f4 --- /dev/null +++ b/src/libaudgui/jump-to-track.cc @@ -0,0 +1,345 @@ +/* + * jump-to-track.c + * Copyright 2007-2014 Yoshiki Yazawa, John Lindgren, and Thomas Lange + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> + +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/playlist.h> +#include <libaudcore/runtime.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" +#include "list.h" +#include "jump-to-track-cache.h" + +static void update_cb (void * data, void *); +static void activate_cb (void * data, void *); + +static JumpToTrackCache cache; +static const KeywordMatches * search_matches; +static GtkWidget * treeview, * filter_entry, * queue_button, * jump_button; +static bool watching = false; + +static void destroy_cb () +{ + if (watching) + { + hook_dissociate ("playlist update", update_cb); + hook_dissociate ("playlist activate", activate_cb); + watching = false; + } + + cache.clear (); + + search_matches = nullptr; +} + +static int get_selected_entry () +{ + g_return_val_if_fail (treeview && search_matches, -1); + + GtkTreeModel * model = gtk_tree_view_get_model ((GtkTreeView *) treeview); + GtkTreeSelection * selection = gtk_tree_view_get_selection ((GtkTreeView *) treeview); + GtkTreeIter iter; + + if (! gtk_tree_selection_get_selected (selection, nullptr, & iter)) + return -1; + + GtkTreePath * path = gtk_tree_model_get_path (model, & iter); + int row = gtk_tree_path_get_indices (path)[0]; + gtk_tree_path_free (path); + + g_return_val_if_fail (row >= 0 && row < search_matches->len (), -1); + return (* search_matches)[row].entry; +} + +static void do_jump (void *) +{ + int entry = get_selected_entry (); + if (entry < 0) + return; + + auto playlist = Playlist::active_playlist (); + playlist.set_position (entry); + playlist.start_playback (); + + if (aud_get_bool ("audgui", "close_jtf_dialog")) + audgui_jump_to_track_hide (); +} + +static void update_queue_button (int entry) +{ + g_return_if_fail (queue_button); + + if (entry < 0) + { + gtk_button_set_label ((GtkButton *) queue_button, _("_Queue")); + gtk_widget_set_sensitive (queue_button, false); + } + else + { + if (Playlist::active_playlist ().queue_find_entry (entry) >= 0) + gtk_button_set_label ((GtkButton *) queue_button, _("Un_queue")); + else + gtk_button_set_label ((GtkButton *) queue_button, _("_Queue")); + + gtk_widget_set_sensitive (queue_button, true); + } +} + +static void do_queue (void *) +{ + auto playlist = Playlist::active_playlist (); + int entry = get_selected_entry (); + if (entry < 0) + return; + + int queued = playlist.queue_find_entry (entry); + if (queued >= 0) + playlist.queue_remove (queued); + else + playlist.queue_insert (-1, entry); + + update_queue_button (entry); +} + +static void selection_changed () +{ + int entry = get_selected_entry (); + gtk_widget_set_sensitive (jump_button, entry >= 0); + + update_queue_button (entry); +} + +static gboolean keypress_cb (GtkWidget * widget, GdkEventKey * event) +{ + if (event->keyval == GDK_KEY_Escape) + { + audgui_jump_to_track_hide (); + return true; + } + + return false; +} + +static void fill_list () +{ + g_return_if_fail (treeview && filter_entry); + + search_matches = cache.search (gtk_entry_get_text ((GtkEntry *) filter_entry)); + + audgui_list_delete_rows (treeview, 0, audgui_list_row_count (treeview)); + audgui_list_insert_rows (treeview, 0, search_matches->len ()); + + if (search_matches->len () >= 1) + { + GtkTreeSelection * sel = gtk_tree_view_get_selection ((GtkTreeView *) treeview); + GtkTreePath * path = gtk_tree_path_new_from_indices (0, -1); + gtk_tree_selection_select_path (sel, path); + gtk_tree_path_free (path); + } +} + +static void update_cb (void * data, void *) +{ + g_return_if_fail (treeview); + + GtkTreeModel * model; + GtkTreeIter iter; + GtkTreePath * path = nullptr; + + auto level = aud::from_ptr<Playlist::UpdateLevel> (data); + if (level <= Playlist::Selection) + return; + + cache.clear (); + + /* If it's only a metadata update, save and restore the cursor position. */ + if (level <= Playlist::Metadata && + gtk_tree_selection_get_selected (gtk_tree_view_get_selection + ((GtkTreeView *) treeview), & model, & iter)) + path = gtk_tree_model_get_path (model, & iter); + + fill_list (); + + if (path != nullptr) + { + gtk_tree_selection_select_path (gtk_tree_view_get_selection + ((GtkTreeView *) treeview), path); + gtk_tree_view_scroll_to_cell ((GtkTreeView *) treeview, path, nullptr, true, 0.5, 0); + gtk_tree_path_free (path); + } +} + +static void activate_cb (void * data, void *) +{ + update_cb (aud::to_ptr (Playlist::Structure), nullptr); +} + +static void filter_icon_cb (GtkEntry * entry) +{ + gtk_entry_set_text (entry, ""); +} + +static void toggle_button_cb (GtkToggleButton * toggle) +{ + aud_set_bool ("audgui", "close_jtf_dialog", gtk_toggle_button_get_active (toggle)); +} + +static void list_get_value (void * user, int row, int column, GValue * value) +{ + g_return_if_fail (search_matches); + g_return_if_fail (column >= 0 && column < 2); + g_return_if_fail (row >= 0 && row < search_matches->len ()); + + auto playlist = Playlist::active_playlist (); + int entry = (* search_matches)[row].entry; + + switch (column) + { + case 0: + g_value_set_int (value, 1 + entry); + break; + case 1: + Tuple tuple = playlist.entry_tuple (entry, Playlist::NoWait); + g_value_set_string (value, tuple.get_str (Tuple::FormattedTitle)); + break; + } +} + +static const AudguiListCallbacks callbacks = { + list_get_value +}; + +static GtkWidget * create_window () +{ + int dpi = audgui_get_dpi (); + + GtkWidget * jump_to_track_win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_type_hint ((GtkWindow *) jump_to_track_win, GDK_WINDOW_TYPE_HINT_DIALOG); + + gtk_window_set_title ((GtkWindow *) jump_to_track_win, _("Jump to Song")); + + g_signal_connect (jump_to_track_win, "key_press_event", (GCallback) keypress_cb, nullptr); + g_signal_connect (jump_to_track_win, "destroy", (GCallback) destroy_cb, nullptr); + + gtk_container_set_border_width ((GtkContainer *) jump_to_track_win, 10); + gtk_window_set_default_size ((GtkWindow *) jump_to_track_win, 6 * dpi, 5 * dpi); + + GtkWidget * vbox = gtk_vbox_new (false, 6); + gtk_container_add ((GtkContainer *) jump_to_track_win, vbox); + + treeview = audgui_list_new (& callbacks, nullptr, 0); + gtk_tree_view_set_headers_visible ((GtkTreeView *) treeview, false); + + audgui_list_add_column (treeview, nullptr, 0, G_TYPE_INT, 7); + audgui_list_add_column (treeview, nullptr, 1, G_TYPE_STRING, -1); + + g_signal_connect (gtk_tree_view_get_selection ((GtkTreeView *) treeview), + "changed", (GCallback) selection_changed, nullptr); + g_signal_connect (treeview, "row-activated", (GCallback) do_jump, nullptr); + + GtkWidget * hbox = gtk_hbox_new (false, 6); + gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 3); + + /* filter box */ + GtkWidget * search_label = gtk_label_new (_("Filter: ")); + gtk_label_set_markup_with_mnemonic ((GtkLabel *) search_label, _("_Filter:")); + gtk_box_pack_start ((GtkBox *) hbox, search_label, false, false, 0); + + filter_entry = gtk_entry_new (); + gtk_entry_set_icon_from_icon_name ((GtkEntry *) filter_entry, + GTK_ENTRY_ICON_SECONDARY, "edit-clear"); + gtk_label_set_mnemonic_widget ((GtkLabel *) search_label, filter_entry); + g_signal_connect (filter_entry, "changed", (GCallback) fill_list, nullptr); + g_signal_connect (filter_entry, "icon-press", (GCallback) filter_icon_cb, nullptr); + gtk_entry_set_activates_default ((GtkEntry *) filter_entry, true); + gtk_box_pack_start ((GtkBox *) hbox, filter_entry, true, true, 0); + + GtkWidget * scrollwin = gtk_scrolled_window_new (nullptr, nullptr); + gtk_container_add ((GtkContainer *) scrollwin, treeview); + gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrollwin, + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrollwin, GTK_SHADOW_IN); + gtk_box_pack_start ((GtkBox *) vbox, scrollwin, true, true, 0); + + GtkWidget * hbox2 = gtk_hbox_new (false, 0); + gtk_box_pack_end ((GtkBox *) vbox, hbox2, false, false, 0); + + GtkWidget * bbox = gtk_hbutton_box_new (); + gtk_button_box_set_layout ((GtkButtonBox *) bbox, GTK_BUTTONBOX_END); + gtk_box_set_spacing ((GtkBox *) bbox, 6); + + GtkWidget * alignment = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_alignment_set_padding ((GtkAlignment *) alignment, 0, 0, 6, 0); + gtk_container_add ((GtkContainer *) alignment, bbox); + gtk_box_pack_end ((GtkBox *) hbox2, alignment, true, true, 0); + + /* close dialog toggle */ + GtkWidget * toggle = gtk_check_button_new_with_mnemonic (_("C_lose on jump")); + gtk_toggle_button_set_active ((GtkToggleButton *) toggle, aud_get_bool + ("audgui", "close_jtf_dialog")); + gtk_container_add ((GtkContainer *) hbox2, toggle); + g_signal_connect (toggle, "clicked", (GCallback) toggle_button_cb, nullptr); + + /* queue button */ + queue_button = audgui_button_new (_("_Queue"), nullptr, do_queue, nullptr); + gtk_container_add ((GtkContainer *) bbox, queue_button); + + /* close button */ + GtkWidget * close = audgui_button_new (_("_Close"), "window-close", + (AudguiCallback) audgui_jump_to_track_hide, nullptr); + gtk_container_add ((GtkContainer *) bbox, close); + + /* jump button */ + jump_button = audgui_button_new (_("_Jump"), "go-jump", do_jump, nullptr); + gtk_container_add ((GtkContainer *) bbox, jump_button); + gtk_widget_set_can_default (jump_button, true); + gtk_widget_grab_default (jump_button); + + return jump_to_track_win; +} + +EXPORT void audgui_jump_to_track () +{ + if (audgui_reshow_unique_window (AUDGUI_JUMP_TO_TRACK_WINDOW)) + return; + + GtkWidget * jump_to_track_win = create_window (); + + if (! watching) + { + fill_list (); + hook_associate ("playlist update", update_cb, nullptr); + hook_associate ("playlist activate", activate_cb, nullptr); + watching = true; + } + + gtk_widget_grab_focus (filter_entry); + + audgui_show_unique_window (AUDGUI_JUMP_TO_TRACK_WINDOW, jump_to_track_win); +} + +EXPORT void audgui_jump_to_track_hide () +{ + audgui_hide_unique_window (AUDGUI_JUMP_TO_TRACK_WINDOW); +} diff --git a/src/libaudgui/libaudgui-gtk.h b/src/libaudgui/libaudgui-gtk.h new file mode 100644 index 0000000..e0b321b --- /dev/null +++ b/src/libaudgui/libaudgui-gtk.h @@ -0,0 +1,95 @@ +/* + * libaudgui-gtk.h + * Copyright 2010-2012 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDGUI_GTK_H +#define LIBAUDGUI_GTK_H + +#include <stdint.h> +#include <gtk/gtk.h> + +#include <libaudcore/objects.h> + +#define audgui_create_widgets(b, w) audgui_create_widgets_with_domain (b, w, PACKAGE) + +enum class AudMenuID; +struct PreferencesWidget; + +typedef void (* AudguiCallback) (void * data); + +class AudguiPixbuf : public SmartPtr<GdkPixbuf, aud::typed_func<GdkPixbuf, g_object_unref>> +{ +public: + AudguiPixbuf () : SmartPtr () {} + explicit AudguiPixbuf (GdkPixbuf * ptr) : SmartPtr (ptr) {} + + int width () + { return gdk_pixbuf_get_width (get ()); } + int height () + { return gdk_pixbuf_get_height (get ()); } + + AudguiPixbuf ref () + { return AudguiPixbuf (get () ? (GdkPixbuf *) g_object_ref (get ()) : nullptr); } +}; + +/* pixbufs.c */ +AudguiPixbuf audgui_pixbuf_from_data (const void * data, int64_t size); +AudguiPixbuf audgui_pixbuf_fallback (); +void audgui_pixbuf_scale_within (AudguiPixbuf & pixbuf, int size); +AudguiPixbuf audgui_pixbuf_request (const char * filename, bool * queued = nullptr); +AudguiPixbuf audgui_pixbuf_request_current (bool * queued = nullptr); + +/* plugin-menu.c */ +GtkWidget * audgui_get_plugin_menu (AudMenuID id); + +/* prefs-widget.c */ +void audgui_create_widgets_with_domain (GtkWidget * box, + ArrayRef<PreferencesWidget> widgets, const char * domain); + +/* scaled-image.c -- okay to use without audgui_init() */ +GtkWidget * audgui_scaled_image_new (GdkPixbuf * pixbuf); +void audgui_scaled_image_set (GtkWidget * widget, GdkPixbuf * pixbuf); + +/* util.c -- okay to use without audgui_init() */ +int audgui_get_dpi (); +int audgui_to_native_dpi (int size); +int audgui_to_portable_dpi (int size); +int audgui_get_digit_width (GtkWidget * widget); +void audgui_get_mouse_coords (GtkWidget * widget, int * x, int * y); +void audgui_get_mouse_coords (GdkScreen * screen, int * x, int * y); +void audgui_get_monitor_geometry (GdkScreen * screen, int x, int y, GdkRectangle * geom); +void audgui_destroy_on_escape (GtkWidget * widget); +void audgui_simple_message (GtkWidget * * widget, GtkMessageType type, + const char * title, const char * text); + +GtkWidget * audgui_button_new (const char * text, const char * icon, + AudguiCallback callback, void * data); + +GtkWidget * audgui_file_entry_new (GtkFileChooserAction action, const char * title); +String audgui_file_entry_get_uri (GtkWidget * entry); +void audgui_file_entry_set_uri (GtkWidget * entry, const char * uri); + +GtkWidget * audgui_dialog_new (GtkMessageType type, const char * title, + const char * text, GtkWidget * button1, GtkWidget * button2); +void audgui_dialog_add_widget (GtkWidget * dialog, GtkWidget * widget); + +cairo_pattern_t * audgui_dark_bg_gradient (const GdkColor & base, int height); +void audgui_vis_bar_color (const GdkColor & hue, int bar, int n_bars, + float & r, float & g, float & b); + +#endif diff --git a/src/libaudgui/libaudgui.h b/src/libaudgui/libaudgui.h new file mode 100644 index 0000000..020c611 --- /dev/null +++ b/src/libaudgui/libaudgui.h @@ -0,0 +1,101 @@ +/* + * libaudgui.h + * Copyright 2007-2013 Giacomo Lozito, Tomasz Moń, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDGUI_H +#define LIBAUDGUI_H + +#include <libaudcore/index.h> +#include <libaudcore/objects.h> + +enum class AudMenuID; +enum class PluginType; +class Playlist; +class PluginHandle; +struct EqualizerPreset; + +/* about.c */ +void audgui_show_about_window (); +void audgui_hide_about_window (); + +/* confirm.c */ +void audgui_confirm_playlist_delete (Playlist playlist); +void audgui_show_playlist_rename (Playlist playlist); + +/* eq-preset.c */ +void audgui_show_eq_preset_window (); +void audgui_import_eq_presets (const Index<EqualizerPreset> & presets); + +/* equalizer.c */ +void audgui_show_equalizer_window (); +void audgui_hide_equalizer_window (); + +/* infopopup.c */ +void audgui_infopopup_show (Playlist playlist, int entry); +void audgui_infopopup_show_current (); +void audgui_infopopup_hide (); + +/* file-opener.c */ +void audgui_run_filebrowser (bool open); +void audgui_hide_filebrowser (); + +/* infowin.c */ +void audgui_infowin_show (Playlist playlist, int entry); +void audgui_infowin_show_current (); +void audgui_infowin_hide (); + +/* init.c */ +void audgui_init (); +void audgui_cleanup (); + +/* jump-to-time.c */ +void audgui_jump_to_time (); + +/* jump-to-track.c */ +void audgui_jump_to_track (); +void audgui_jump_to_track_hide (); + +/* playlists.c */ +void audgui_import_playlist (); +void audgui_export_playlist (); + +/* plugin-menu.c */ +void audgui_plugin_menu_add (AudMenuID id, void (* func) (), const char * name, const char * icon); +void audgui_plugin_menu_remove (AudMenuID id, void (* func) ()); + +/* plugin-prefs.c */ +void audgui_show_plugin_about (PluginHandle * plugin); +void audgui_show_plugin_prefs (PluginHandle * plugin); + +/* prefs-window.c */ +void audgui_show_prefs_window (); +void audgui_show_prefs_for_plugin_type (PluginType type); +void audgui_hide_prefs_window (); + +/* queue-manager.c */ +void audgui_queue_manager_show (); + +/* urilist.c */ +void audgui_urilist_open (const char * list); +void audgui_urilist_insert (Playlist playlist, int position, const char * list); +Index<char> audgui_urilist_create_from_selected (Playlist playlist); + +/* url-opener.c */ +void audgui_show_add_url_window (bool open); + +#endif /* LIBAUDGUI_H */ diff --git a/src/libaudgui/list.cc b/src/libaudgui/list.cc new file mode 100644 index 0000000..7f68061 --- /dev/null +++ b/src/libaudgui/list.cc @@ -0,0 +1,908 @@ +/* + * list.c + * Copyright 2011-2013 John Lindgren and Michał Lipski + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stddef.h> +#include <gtk/gtk.h> + +#include <libaudcore/hook.h> +#include <libaudcore/objects.h> + +#include "libaudgui-gtk.h" +#include "list.h" + +enum { + HIGHLIGHT_COLUMN, + RESERVED_COLUMNS +}; + +#define MODEL_HAS_CB(m, cb) \ + ((m)->cbs_size > (int) offsetof (AudguiListCallbacks, cb) && (m)->cbs->cb) +#define PATH_IS_SELECTED(w, p) (gtk_tree_selection_path_is_selected \ + (gtk_tree_view_get_selection ((GtkTreeView *) (w)), (p))) + +struct ListModel { + GObject parent; + const AudguiListCallbacks * cbs; + int cbs_size; + void * user; + int charwidth; + int rows, highlight; + int columns; + GList * column_types; + bool resizable; + bool frozen, blocked; + bool dragging; + int clicked_row, receive_row; + int scroll_speed; +}; + +/* ==== MODEL ==== */ + +static GtkTreeModelFlags list_model_get_flags (GtkTreeModel * model) +{ + return GTK_TREE_MODEL_LIST_ONLY; +} + +static int list_model_get_n_columns (GtkTreeModel * model) +{ + return ((ListModel *) model)->columns; +} + +static GType list_model_get_column_type (GtkTreeModel * _model, int column) +{ + ListModel * model = (ListModel *) _model; + g_return_val_if_fail (column >= 0 && column < model->columns, G_TYPE_INVALID); + + if (column == HIGHLIGHT_COLUMN) + return PANGO_TYPE_WEIGHT; + + return GPOINTER_TO_INT (g_list_nth_data (model->column_types, column - + RESERVED_COLUMNS)); +} + +static gboolean list_model_get_iter (GtkTreeModel * model, GtkTreeIter * iter, + GtkTreePath * path) +{ + int row = gtk_tree_path_get_indices (path)[0]; + if (row < 0 || row >= ((ListModel *) model)->rows) + return false; + iter->user_data = GINT_TO_POINTER (row); + return true; +} + +static GtkTreePath * list_model_get_path (GtkTreeModel * model, + GtkTreeIter * iter) +{ + int row = GPOINTER_TO_INT (iter->user_data); + g_return_val_if_fail (row >= 0 && row < ((ListModel *) model)->rows, nullptr); + return gtk_tree_path_new_from_indices (row, -1); +} + +static void list_model_get_value (GtkTreeModel * _model, GtkTreeIter * iter, + int column, GValue * value) +{ + ListModel * model = (ListModel *) _model; + int row = GPOINTER_TO_INT (iter->user_data); + g_return_if_fail (column >= 0 && column < model->columns); + g_return_if_fail (row >= 0 && row < model->rows); + + if (column == HIGHLIGHT_COLUMN) + { + g_value_init (value, PANGO_TYPE_WEIGHT); + g_value_set_enum (value, row == model->highlight ? PANGO_WEIGHT_BOLD : + PANGO_WEIGHT_NORMAL); + return; + } + + g_value_init (value, GPOINTER_TO_INT (g_list_nth_data (model->column_types, + column - RESERVED_COLUMNS))); + model->cbs->get_value (model->user, row, column - RESERVED_COLUMNS, value); +} + +static gboolean list_model_iter_next (GtkTreeModel * _model, GtkTreeIter * iter) +{ + ListModel * model = (ListModel *) _model; + int row = GPOINTER_TO_INT (iter->user_data); + g_return_val_if_fail (row >= 0 && row < model->rows, false); + if (row + 1 >= model->rows) + return false; + iter->user_data = GINT_TO_POINTER (row + 1); + return true; +} + +static gboolean list_model_iter_children (GtkTreeModel * model, + GtkTreeIter * iter, GtkTreeIter * parent) +{ + if (parent || ((ListModel *) model)->rows < 1) + return false; + iter->user_data = GINT_TO_POINTER (0); + return true; +} + +static gboolean list_model_iter_has_child (GtkTreeModel * model, + GtkTreeIter * iter) +{ + return false; +} + +static int list_model_iter_n_children (GtkTreeModel * model, GtkTreeIter * iter) +{ + return iter ? 0 : ((ListModel *) model)->rows; +} + +static gboolean list_model_iter_nth_child (GtkTreeModel * model, + GtkTreeIter * iter, GtkTreeIter * parent, int n) +{ + if (parent || n < 0 || n >= ((ListModel *) model)->rows) + return false; + iter->user_data = GINT_TO_POINTER (n); + return true; +} + +static gboolean list_model_iter_parent (GtkTreeModel * model, + GtkTreeIter * iter, GtkTreeIter * child) +{ + return false; +} + +static void iface_init (GtkTreeModelIface * iface) +{ + iface->get_flags = list_model_get_flags; + iface->get_n_columns = list_model_get_n_columns; + iface->get_column_type = list_model_get_column_type; + iface->get_iter = list_model_get_iter; + iface->get_path = list_model_get_path; + iface->get_value = list_model_get_value; + iface->iter_next = list_model_iter_next; + iface->iter_children = list_model_iter_children; + iface->iter_has_child = list_model_iter_has_child; + iface->iter_n_children = list_model_iter_n_children; + iface->iter_nth_child = list_model_iter_nth_child; + iface->iter_parent = list_model_iter_parent; +} + +static const GInterfaceInfo iface_info = { + (GInterfaceInitFunc) iface_init +}; + +static GType list_model_get_type () +{ + static GType type = G_TYPE_INVALID; + if (type == G_TYPE_INVALID) + { + type = g_type_register_static_simple (G_TYPE_OBJECT, "AudguiListModel", + sizeof (GObjectClass), nullptr, sizeof (ListModel), nullptr, (GTypeFlags) 0); + g_type_add_interface_static (type, GTK_TYPE_TREE_MODEL, & iface_info); + } + return type; +} + +/* ==== CALLBACKS ==== */ + +static gboolean select_allow_cb (GtkTreeSelection * sel, GtkTreeModel * model, + GtkTreePath * path, gboolean was, void * user) +{ + return ! ((ListModel *) model)->frozen; +} + +static void select_row_cb (GtkTreeModel * _model, GtkTreePath * path, + GtkTreeIter * iter, void * user) +{ + ListModel * model = (ListModel *) _model; + int row = gtk_tree_path_get_indices (path)[0]; + g_return_if_fail (row >= 0 && row < model->rows); + model->cbs->set_selected (model->user, row, true); +} + +static void select_cb (GtkTreeSelection * sel, ListModel * model) +{ + if (model->blocked) + return; + model->cbs->select_all (model->user, false); + gtk_tree_selection_selected_foreach (sel, select_row_cb, nullptr); +} + +static void focus_cb (GtkTreeView * tree, ListModel * model) +{ + if (! model->blocked) + model->cbs->focus_change (model->user, + audgui_list_get_focus ((GtkWidget *) tree)); +} + +static void activate_cb (GtkTreeView * tree, GtkTreePath * path, + GtkTreeViewColumn * col, ListModel * model) +{ + int row = gtk_tree_path_get_indices (path)[0]; + g_return_if_fail (row >= 0 && row < model->rows); + model->cbs->activate_row (model->user, row); +} + +static gboolean button_press_cb (GtkWidget * widget, GdkEventButton * event, + ListModel * model) +{ + GtkTreePath * path = nullptr; + gtk_tree_view_get_path_at_pos ((GtkTreeView *) widget, event->x, event->y, + & path, nullptr, nullptr, nullptr); + + if (event->type == GDK_BUTTON_PRESS && event->button == 3 + && MODEL_HAS_CB (model, right_click)) + { + /* Only allow GTK to select this row if it is not already selected. We + * don't want to clear a multiple selection. */ + if (path) + { + if (PATH_IS_SELECTED (widget, path)) + model->frozen = true; + gtk_tree_view_set_cursor ((GtkTreeView *) widget, path, nullptr, false); + model->frozen = false; + } + + model->cbs->right_click (model->user, event); + + if (path) + gtk_tree_path_free (path); + return true; + } + + /* Only allow GTK to select this row if it is not already selected. If we + * are going to be dragging, we don't want to clear a multiple selection. + * If this is just a simple click, we will clear the multiple selection in + * button_release_cb. */ + if (event->type == GDK_BUTTON_PRESS && event->button == 1 && ! (event->state + & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) && path && PATH_IS_SELECTED (widget, + path)) + model->frozen = true; + + if (path) + model->clicked_row = gtk_tree_path_get_indices (path)[0]; + else + model->clicked_row = -1; + + if (path) + gtk_tree_path_free (path); + return false; +} + +static gboolean button_release_cb (GtkWidget * widget, GdkEventButton * event, + ListModel * model) +{ + /* If button_press_cb set "frozen", and we were not dragging, we need to + * clear a multiple selection. */ + if (model->frozen && model->clicked_row >= 0 && model->clicked_row < + model->rows) + { + model->frozen = false; + GtkTreePath * path = gtk_tree_path_new_from_indices (model->clicked_row, -1); + gtk_tree_view_set_cursor ((GtkTreeView *) widget, path, nullptr, false); + gtk_tree_path_free (path); + } + + return false; +} + +static gboolean key_press_cb (GtkWidget * widget, GdkEventKey * event, ListModel * model) +{ + /* GTK thinks the spacebar should activate a row; I (jlindgren) disagree */ + if (event->keyval == ' ' && ! (event->state & GDK_CONTROL_MASK)) + return true; + + return false; +} + +static gboolean motion_notify_cb (GtkWidget * widget, GdkEventMotion * event, ListModel * model) +{ + if (MODEL_HAS_CB (model, mouse_motion)) + { + int x, y; + gtk_tree_view_convert_bin_window_to_widget_coords ((GtkTreeView *) + widget, event->x, event->y, & x, & y); + + int row = audgui_list_row_at_point (widget, x, y); + model->cbs->mouse_motion (model->user, event, row); + } + + return false; +} + +static gboolean leave_notify_cb (GtkWidget * widget, GdkEventMotion * event, ListModel * model) +{ + if (MODEL_HAS_CB (model, mouse_leave)) + { + int x, y; + gtk_tree_view_convert_bin_window_to_widget_coords ((GtkTreeView *) + widget, event->x, event->y, & x, & y); + + int row = audgui_list_row_at_point (widget, x, y); + model->cbs->mouse_leave (model->user, event, row); + } + + return false; +} + +/* ==== DRAG AND DROP ==== */ + +static void drag_begin (GtkWidget * widget, GdkDragContext * context, + ListModel * model) +{ + g_signal_stop_emission_by_name (widget, "drag-begin"); + + model->dragging = true; + + /* If button_press_cb preserved a multiple selection, tell button_release_cb + * not to clear it. */ + model->frozen = false; +} + +static void drag_end (GtkWidget * widget, GdkDragContext * context, + ListModel * model) +{ + g_signal_stop_emission_by_name (widget, "drag-end"); + + model->dragging = false; + model->clicked_row = -1; +} + +static void drag_data_get (GtkWidget * widget, GdkDragContext * context, + GtkSelectionData * sel, unsigned info, unsigned time, ListModel * model) +{ + g_signal_stop_emission_by_name (widget, "drag-data-get"); + + Index<char> data = model->cbs->get_data (model->user); + gtk_selection_data_set (sel, gdk_atom_intern (model->cbs->data_type, false), + 8, (const unsigned char *) data.begin (), data.len ()); +} + +static void get_scroll_pos (GtkAdjustment * adj, int & pos, int & end) +{ + pos = gtk_adjustment_get_value (adj); + end = gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj); +} + +static bool can_scroll (int pos, int end, int speed) +{ + if (speed > 0) + return pos < end; + if (speed < 0) + return pos > 0; + + return false; +} + +static void autoscroll (void * widget) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model + ((GtkTreeView *) widget); + + GtkAdjustment * adj = gtk_tree_view_get_vadjustment ((GtkTreeView *) widget); + g_return_if_fail (adj); + + int pos, end; + get_scroll_pos (adj, pos, end); + pos = aud::clamp (pos + model->scroll_speed, 0, end); + gtk_adjustment_set_value (adj, pos); + + if (! can_scroll (pos, end, model->scroll_speed)) + { + model->scroll_speed = 0; + timer_remove (TimerRate::Hz30, autoscroll, widget); + } +} + +static void start_autoscroll (ListModel * model, GtkWidget * widget, int speed) +{ + GtkAdjustment * adj = gtk_tree_view_get_vadjustment ((GtkTreeView *) widget); + g_return_if_fail (adj); + + int pos, end; + get_scroll_pos (adj, pos, end); + + if (can_scroll (pos, end, speed)) + { + model->scroll_speed = speed; + timer_add (TimerRate::Hz30, autoscroll, widget); + } +} + +static void stop_autoscroll (ListModel * model, GtkWidget * widget) +{ + model->scroll_speed = 0; + timer_remove (TimerRate::Hz30, autoscroll, widget); +} + +static gboolean drag_motion (GtkWidget * widget, GdkDragContext * context, + int x, int y, unsigned time, ListModel * model) +{ + g_signal_stop_emission_by_name (widget, "drag-motion"); + + if (model->dragging && MODEL_HAS_CB (model, shift_rows)) + gdk_drag_status (context, GDK_ACTION_MOVE, time); /* dragging within same list */ + else if (MODEL_HAS_CB (model, data_type) && MODEL_HAS_CB (model, receive_data)) + gdk_drag_status (context, GDK_ACTION_COPY, time); /* cross-widget dragging */ + else + return false; + + if (model->rows > 0) + { + int row = audgui_list_row_at_point_rounded (widget, x, y); + if (row == model->rows) + { + GtkTreePath * path = gtk_tree_path_new_from_indices (row - 1, -1); + gtk_tree_view_set_drag_dest_row ((GtkTreeView *) widget, path, + GTK_TREE_VIEW_DROP_AFTER); + gtk_tree_path_free (path); + } + else + { + GtkTreePath * path = gtk_tree_path_new_from_indices (row, -1); + gtk_tree_view_set_drag_dest_row ((GtkTreeView *) widget, path, + GTK_TREE_VIEW_DROP_BEFORE); + gtk_tree_path_free (path); + } + } + + gtk_tree_view_convert_widget_to_bin_window_coords ((GtkTreeView *) widget, + x, y, & x, & y); + + int height = gdk_window_get_height (gtk_tree_view_get_bin_window ((GtkTreeView *) widget)); + int hotspot = aud::min (height / 4, audgui_get_dpi () / 2); + + if (y >= 0 && y < hotspot) + start_autoscroll (model, widget, y - hotspot); + else if (y >= height - hotspot && y < height) + start_autoscroll (model, widget, y - (height - hotspot)); + else + stop_autoscroll (model, widget); + + return true; +} + +static void drag_leave (GtkWidget * widget, GdkDragContext * context, + unsigned time, ListModel * model) +{ + g_signal_stop_emission_by_name (widget, "drag-leave"); + + gtk_tree_view_set_drag_dest_row ((GtkTreeView *) widget, nullptr, (GtkTreeViewDropPosition) 0); + stop_autoscroll (model, widget); +} + +static gboolean drag_drop (GtkWidget * widget, GdkDragContext * context, int x, + int y, unsigned time, ListModel * model) +{ + g_signal_stop_emission_by_name (widget, "drag-drop"); + + gboolean success = true; + int row = audgui_list_row_at_point_rounded (widget, x, y); + + if (model->dragging && MODEL_HAS_CB (model, shift_rows)) + { + /* dragging within same list */ + if (model->clicked_row >= 0 && model->clicked_row < model->rows) + model->cbs->shift_rows (model->user, model->clicked_row, row); + else + success = false; + } + else if (MODEL_HAS_CB (model, data_type) && MODEL_HAS_CB (model, receive_data)) + { + /* cross-widget dragging */ + model->receive_row = row; + gtk_drag_get_data (widget, context, gdk_atom_intern + (model->cbs->data_type, false), time); + } + else + success = false; + + gtk_drag_finish (context, success, false, time); + gtk_tree_view_set_drag_dest_row ((GtkTreeView *) widget, nullptr, (GtkTreeViewDropPosition) 0); + stop_autoscroll (model, widget); + return true; +} + +static void drag_data_received (GtkWidget * widget, GdkDragContext * context, int x, + int y, GtkSelectionData * sel, unsigned info, unsigned time, ListModel * model) +{ + g_signal_stop_emission_by_name (widget, "drag-data-received"); + + g_return_if_fail (model->receive_row >= 0 && model->receive_row <= + model->rows); + + auto data = (const char *) gtk_selection_data_get_data (sel); + int length = gtk_selection_data_get_length (sel); + + if (data && length) + model->cbs->receive_data (model->user, model->receive_row, data, length); + + model->receive_row = -1; +} + +/* ==== PUBLIC FUNCS ==== */ + +static void destroy_cb (GtkWidget * list, ListModel * model) +{ + stop_autoscroll (model, list); + g_list_free (model->column_types); + g_object_unref (model); +} + +static void update_selection (GtkWidget * list, ListModel * model, int at, + int rows) +{ + model->blocked = true; + GtkTreeSelection * sel = gtk_tree_view_get_selection ((GtkTreeView *) list); + + for (int i = at; i < at + rows; i ++) + { + GtkTreeIter iter = {0, GINT_TO_POINTER (i)}; + if (model->cbs->get_selected (model->user, i)) + gtk_tree_selection_select_iter (sel, & iter); + else + gtk_tree_selection_unselect_iter (sel, & iter); + } + + model->blocked = false; +} + +EXPORT GtkWidget * audgui_list_new_real (const AudguiListCallbacks * cbs, int cbs_size, + void * user, int rows) +{ + g_return_val_if_fail (cbs->get_value, nullptr); + + ListModel * model = (ListModel *) g_object_new (list_model_get_type (), nullptr); + model->cbs = cbs; + model->cbs_size = cbs_size; + model->user = user; + model->rows = rows; + model->highlight = -1; + model->columns = RESERVED_COLUMNS; + model->column_types = nullptr; + model->resizable = true; + model->frozen = false; + model->blocked = false; + model->dragging = false; + model->clicked_row = -1; + model->receive_row = -1; + model->scroll_speed = 0; + + GtkWidget * list = gtk_tree_view_new_with_model ((GtkTreeModel *) model); + gtk_tree_view_set_fixed_height_mode ((GtkTreeView *) list, true); + g_signal_connect (list, "destroy", (GCallback) destroy_cb, model); + + model->charwidth = audgui_get_digit_width (list); + + if (MODEL_HAS_CB (model, get_selected) && MODEL_HAS_CB (model, set_selected) + && MODEL_HAS_CB (model, select_all)) + { + GtkTreeSelection * sel = gtk_tree_view_get_selection + ((GtkTreeView *) list); + gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); + gtk_tree_selection_set_select_function (sel, select_allow_cb, nullptr, nullptr); + g_signal_connect (sel, "changed", (GCallback) select_cb, model); + + update_selection (list, model, 0, rows); + } + + if (MODEL_HAS_CB (model, focus_change)) + g_signal_connect (list, "cursor-changed", (GCallback) focus_cb, model); + + if (MODEL_HAS_CB (model, activate_row)) + g_signal_connect (list, "row-activated", (GCallback) activate_cb, model); + + g_signal_connect (list, "button-press-event", (GCallback) button_press_cb, model); + g_signal_connect (list, "button-release-event", (GCallback) button_release_cb, model); + g_signal_connect (list, "key-press-event", (GCallback) key_press_cb, model); + g_signal_connect (list, "motion-notify-event", (GCallback) motion_notify_cb, model); + g_signal_connect (list, "leave-notify-event", (GCallback) leave_notify_cb, model); + + gboolean supports_drag = false; + + if (MODEL_HAS_CB (model, data_type) && + (MODEL_HAS_CB (model, get_data) || MODEL_HAS_CB (model, receive_data))) + { + const GtkTargetEntry target = {(char *) cbs->data_type, 0, 0}; + + if (MODEL_HAS_CB (model, get_data)) + { + gtk_drag_source_set (list, GDK_BUTTON1_MASK, & target, 1, GDK_ACTION_COPY); + g_signal_connect (list, "drag-data-get", (GCallback) drag_data_get, model); + } + + if (MODEL_HAS_CB (model, receive_data)) + { + gtk_drag_dest_set (list, (GtkDestDefaults) 0, & target, 1, GDK_ACTION_COPY); + g_signal_connect (list, "drag-data-received", (GCallback) drag_data_received, model); + } + + supports_drag = true; + } + else if (MODEL_HAS_CB (model, shift_rows)) + { + gtk_drag_source_set (list, GDK_BUTTON1_MASK, nullptr, 0, GDK_ACTION_COPY); + gtk_drag_dest_set (list, (GtkDestDefaults) 0, nullptr, 0, GDK_ACTION_COPY); + supports_drag = true; + } + + if (supports_drag) + { + g_signal_connect (list, "drag-begin", (GCallback) drag_begin, model); + g_signal_connect (list, "drag-end", (GCallback) drag_end, model); + g_signal_connect (list, "drag-motion", (GCallback) drag_motion, model); + g_signal_connect (list, "drag-leave", (GCallback) drag_leave, model); + g_signal_connect (list, "drag-drop", (GCallback) drag_drop, model); + } + + return list; +} + +EXPORT void * audgui_list_get_user (GtkWidget * list) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model + ((GtkTreeView *) list); + return model->user; +} + +EXPORT void audgui_list_add_column (GtkWidget * list, const char * title, + int column, GType type, int width, bool use_markup) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model + ((GtkTreeView *) list); + g_return_if_fail (RESERVED_COLUMNS + column == model->columns); + + model->columns ++; + model->column_types = g_list_append (model->column_types, GINT_TO_POINTER + (type)); + + GtkCellRenderer * renderer = gtk_cell_renderer_text_new (); + + GtkTreeViewColumn * tree_column = use_markup ? + gtk_tree_view_column_new_with_attributes + (title, renderer, "markup", RESERVED_COLUMNS + column, nullptr) : + gtk_tree_view_column_new_with_attributes + (title, renderer, "text", RESERVED_COLUMNS + column, "weight", HIGHLIGHT_COLUMN, nullptr); + + gtk_tree_view_column_set_sizing (tree_column, GTK_TREE_VIEW_COLUMN_FIXED); + + int pad1, pad2, pad3; + gtk_widget_style_get (list, "horizontal-separator", & pad1, "focus-line-width", & pad2, nullptr); + gtk_cell_renderer_get_padding (renderer, & pad3, nullptr); + int padding = pad1 + 2 * pad2 + 2 * pad3; + + if (width < 0) + { + gtk_tree_view_column_set_expand (tree_column, true); + model->resizable = false; // columns to the right will not be resizable + } + else + { + gtk_tree_view_column_set_resizable (tree_column, model->resizable); + gtk_tree_view_column_set_min_width (tree_column, + width * model->charwidth + model->charwidth / 2 + padding); + } + + if (width >= 0 && width < 10) + g_object_set ((GObject *) renderer, "xalign", (float) 1, nullptr); + else + g_object_set ((GObject *) renderer, "ellipsize-set", true, "ellipsize", + PANGO_ELLIPSIZE_END, nullptr); + + gtk_tree_view_append_column ((GtkTreeView *) list, tree_column); +} + +EXPORT int audgui_list_row_count (GtkWidget * list) +{ + return ((ListModel *) gtk_tree_view_get_model ((GtkTreeView *) list))->rows; +} + +EXPORT void audgui_list_insert_rows (GtkWidget * list, int at, int rows) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model + ((GtkTreeView *) list); + g_return_if_fail (at >= 0 && at <= model->rows && rows >= 0); + + model->rows += rows; + if (model->highlight >= at) + model->highlight += rows; + + GtkTreeIter iter = {0, GINT_TO_POINTER (at)}; + GtkTreePath * path = gtk_tree_path_new_from_indices (at, -1); + + for (int i = rows; i --; ) + gtk_tree_model_row_inserted ((GtkTreeModel *) model, path, & iter); + + gtk_tree_path_free (path); + + if (model->cbs->get_selected) + update_selection (list, model, at, rows); +} + +EXPORT void audgui_list_update_rows (GtkWidget * list, int at, int rows) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model + ((GtkTreeView *) list); + g_return_if_fail (at >= 0 && rows >= 0 && at + rows <= model->rows); + + GtkTreeIter iter = {0, GINT_TO_POINTER (at)}; + GtkTreePath * path = gtk_tree_path_new_from_indices (at, -1); + + while (rows --) + { + gtk_tree_model_row_changed ((GtkTreeModel *) model, path, & iter); + iter.user_data = GINT_TO_POINTER (GPOINTER_TO_INT (iter.user_data) + 1); + gtk_tree_path_next (path); + } + + gtk_tree_path_free (path); +} + +EXPORT void audgui_list_delete_rows (GtkWidget * list, int at, int rows) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model + ((GtkTreeView *) list); + g_return_if_fail (at >= 0 && rows >= 0 && at + rows <= model->rows); + + model->rows -= rows; + if (model->highlight >= at + rows) + model->highlight -= rows; + else if (model->highlight >= at) + model->highlight = -1; + + model->frozen = true; + model->blocked = true; + + int focus = audgui_list_get_focus (list); + + // first delete rows after cursor so it does not get moved to one of them + if (focus >= at && focus + 1 < at + rows) + { + GtkTreePath * path = gtk_tree_path_new_from_indices (focus + 1, -1); + + while (focus + 1 < at + rows) + { + gtk_tree_model_row_deleted ((GtkTreeModel *) model, path); + rows --; + } + + gtk_tree_path_free (path); + } + + // now delete rows preceding cursor and finally cursor row itself + GtkTreePath * path = gtk_tree_path_new_from_indices (at, -1); + + while (rows --) + gtk_tree_model_row_deleted ((GtkTreeModel *) model, path); + + gtk_tree_path_free (path); + + model->frozen = false; + model->blocked = false; +} + +EXPORT void audgui_list_update_selection (GtkWidget * list, int at, int rows) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model + ((GtkTreeView *) list); + g_return_if_fail (model->cbs->get_selected); + g_return_if_fail (at >= 0 && rows >= 0 && at + rows <= model->rows); + update_selection (list, model, at, rows); +} + +EXPORT int audgui_list_get_highlight (GtkWidget * list) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model + ((GtkTreeView *) list); + return model->highlight; +} + +EXPORT void audgui_list_set_highlight (GtkWidget * list, int row) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model + ((GtkTreeView *) list); + g_return_if_fail (row >= -1 && row < model->rows); + + int old = model->highlight; + if (row == old) + return; + model->highlight = row; + + if (old >= 0) + audgui_list_update_rows (list, old, 1); + if (row >= 0) + audgui_list_update_rows (list, row, 1); +} + +EXPORT int audgui_list_get_focus (GtkWidget * list) +{ + GtkTreePath * path = nullptr; + gtk_tree_view_get_cursor ((GtkTreeView *) list, & path, nullptr); + + if (! path) + return -1; + + int row = gtk_tree_path_get_indices (path)[0]; + + gtk_tree_path_free (path); + return row; +} + +EXPORT void audgui_list_set_focus (GtkWidget * list, int row) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model + ((GtkTreeView *) list); + g_return_if_fail (row >= -1 && row < model->rows); + + if (row < 0 || row == audgui_list_get_focus (list)) + return; + + model->frozen = true; + model->blocked = true; + + GtkTreePath * path = gtk_tree_path_new_from_indices (row, -1); + gtk_tree_view_set_cursor ((GtkTreeView *) list, path, nullptr, false); + gtk_tree_view_scroll_to_cell ((GtkTreeView *) list, path, nullptr, false, 0, 0); + gtk_tree_path_free (path); + + model->frozen = false; + model->blocked = false; +} + +EXPORT int audgui_list_row_at_point (GtkWidget * list, int x, int y) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model ((GtkTreeView *) list); + + GtkTreePath * path = nullptr; + gtk_tree_view_convert_widget_to_bin_window_coords ((GtkTreeView *) list, x, y, & x, & y); + gtk_tree_view_get_path_at_pos ((GtkTreeView *) list, x, y, & path, nullptr, nullptr, nullptr); + + if (! path) + return -1; + + int row = gtk_tree_path_get_indices (path)[0]; + g_return_val_if_fail (row >= 0 && row < model->rows, -1); + + gtk_tree_path_free (path); + return row; +} + +/* note that this variant always returns a valid row (or row + 1) */ +EXPORT int audgui_list_row_at_point_rounded (GtkWidget * list, int x, int y) +{ + ListModel * model = (ListModel *) gtk_tree_view_get_model ((GtkTreeView *) list); + + gtk_tree_view_convert_widget_to_bin_window_coords ((GtkTreeView *) list, x, y, & x, & y); + + /* bound the mouse cursor within the bin window to get the nearest row */ + GdkWindow * bin = gtk_tree_view_get_bin_window ((GtkTreeView *) list); + x = aud::clamp (x, 0, gdk_window_get_width (bin) - 1); + y = aud::clamp (y, 0, gdk_window_get_height (bin) - 1); + + GtkTreePath * path = nullptr; + gtk_tree_view_get_path_at_pos ((GtkTreeView *) list, x, y, & path, nullptr, nullptr, nullptr); + + if (! path) + return model->rows; + + int row = gtk_tree_path_get_indices (path)[0]; + g_return_val_if_fail (row >= 0 && row < model->rows, -1); + + GdkRectangle rect; + gtk_tree_view_get_background_area ((GtkTreeView *) list, path, nullptr, & rect); + if (y > rect.y + rect.height / 2) + row ++; + + gtk_tree_path_free (path); + return row; +} diff --git a/src/libaudgui/list.h b/src/libaudgui/list.h new file mode 100644 index 0000000..7226cd6 --- /dev/null +++ b/src/libaudgui/list.h @@ -0,0 +1,81 @@ +/* + * list.h + * Copyright 2011-2012 John Lindgren and Michał Lipski + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef AUDGUI_LIST_H +#define AUDGUI_LIST_H + +/* okay to use without audgui_init() */ + +#include <gtk/gtk.h> + +#include <libaudcore/index.h> + +/* New callbacks should be added to the end of this struct. The + * audgui_list_new() macro tells us the size of the callback struct as it was + * defined when the caller code was compiled, allowing us to expand the struct + * without breaking backward compatibility. */ + +struct AudguiListCallbacks { + void (* get_value) (void * user, int row, int column, GValue * value); + + /* selection (optional) */ + bool (* get_selected) (void * user, int row); + void (* set_selected) (void * user, int row, bool selected); + void (* select_all) (void * user, bool selected); + + void (* activate_row) (void * user, int row); /* optional */ + void (* right_click) (void * user, GdkEventButton * event); /* optional */ + void (* shift_rows) (void * user, int row, int before); /* optional */ + + /* cross-widget drag and drop (optional) */ + const char * data_type; + Index<char> (* get_data) (void * user); + void (* receive_data) (void * user, int row, const char * data, int len); + + void (* mouse_motion) (void * user, GdkEventMotion * event, int row); /* optional */ + void (* mouse_leave) (void * user, GdkEventMotion * event, int row); /* optional */ + + void (* focus_change) (void * user, int row); /* optional */ +}; + +GtkWidget * audgui_list_new_real (const AudguiListCallbacks * cbs, int cbs_size, + void * user, int rows); + +#define audgui_list_new(c, u, r) \ + audgui_list_new_real (c, sizeof (AudguiListCallbacks), u, r) + +void * audgui_list_get_user (GtkWidget * list); +void audgui_list_add_column (GtkWidget * list, const char * title, + int column, GType type, int width, bool use_markup = false); + +int audgui_list_row_count (GtkWidget * list); +void audgui_list_insert_rows (GtkWidget * list, int at, int rows); +void audgui_list_update_rows (GtkWidget * list, int at, int rows); +void audgui_list_delete_rows (GtkWidget * list, int at, int rows); +void audgui_list_update_selection (GtkWidget * list, int at, int rows); + +int audgui_list_get_highlight (GtkWidget * list); +void audgui_list_set_highlight (GtkWidget * list, int row); +int audgui_list_get_focus (GtkWidget * list); +void audgui_list_set_focus (GtkWidget * list, int row); + +int audgui_list_row_at_point (GtkWidget * list, int x, int y); +int audgui_list_row_at_point_rounded (GtkWidget * list, int x, int y); + +#endif diff --git a/src/libaudgui/menu.cc b/src/libaudgui/menu.cc new file mode 100644 index 0000000..ef5ac34 --- /dev/null +++ b/src/libaudgui/menu.cc @@ -0,0 +1,129 @@ +/* + * menu.c + * Copyright 2011-2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "menu.h" + +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/runtime.h> + +static GtkWidget * image_menu_item_new (const char * text, const char * icon) +{ + GtkWidget * widget = gtk_image_menu_item_new_with_mnemonic (text); + + if (icon) + { + GtkWidget * image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image ((GtkImageMenuItem *) widget, image); + } + + return widget; +} + +static void toggled_cb (GtkCheckMenuItem * check, const AudguiMenuItem * item) +{ + gboolean on = gtk_check_menu_item_get_active (check); + + if (aud_get_bool (item->csect, item->cname) == on) + return; + + aud_set_bool (item->csect, item->cname, on); + + if (item->func) + item->func (); +} + +static void hook_cb (void * data, GtkWidget * check) +{ + const AudguiMenuItem * item = (const AudguiMenuItem *) g_object_get_data + ((GObject *) check, "item"); + gtk_check_menu_item_set_active ((GtkCheckMenuItem *) check, aud_get_bool + (item->csect, item->cname)); +} + +static void unhook_cb (GtkCheckMenuItem * check, const AudguiMenuItem * item) +{ + hook_dissociate (item->hook, (HookFunction) hook_cb, check); +} + +EXPORT GtkWidget * audgui_menu_item_new_with_domain + (const AudguiMenuItem * item, GtkAccelGroup * accel, const char * domain) +{ + const char * name = (domain && item->name) ? dgettext (domain, item->name) : item->name; + GtkWidget * widget = nullptr; + + if (name && item->func && ! item->cname) /* normal widget */ + { + widget = image_menu_item_new (name, item->icon); + g_signal_connect (widget, "activate", item->func, nullptr); + } + else if (name && item->cname) /* toggle widget */ + { + widget = gtk_check_menu_item_new_with_mnemonic (name); + gtk_check_menu_item_set_active ((GtkCheckMenuItem *) widget, + aud_get_bool (item->csect, item->cname)); + g_signal_connect (widget, "toggled", (GCallback) toggled_cb, (void *) item); + + if (item->hook) + { + g_object_set_data ((GObject *) widget, "item", (void *) item); + hook_associate (item->hook, (HookFunction) hook_cb, widget); + g_signal_connect (widget, "destroy", (GCallback) unhook_cb, (void *) item); + } + } + else if (name && (item->items.len || item->get_sub)) /* submenu */ + { + widget = image_menu_item_new (name, item->icon); + + GtkWidget * sub; + + if (item->get_sub) + sub = item->get_sub (); + else + { + sub = gtk_menu_new (); + audgui_menu_init_with_domain (sub, item->items, accel, domain); + } + + gtk_menu_item_set_submenu ((GtkMenuItem *) widget, sub); + } + else if (item->sep) /* separator */ + widget = gtk_separator_menu_item_new (); + + if (widget && accel && item->key) + gtk_widget_add_accelerator (widget, "activate", accel, item->key, + item->mod, GTK_ACCEL_VISIBLE); + + return widget; +} + +EXPORT void audgui_menu_init_with_domain (GtkWidget * shell, + ArrayRef<AudguiMenuItem> items, GtkAccelGroup * accel, + const char * domain) +{ + for (const AudguiMenuItem & item : items) + { + GtkWidget * widget = audgui_menu_item_new_with_domain (& item, accel, domain); + if (! widget) + continue; + + gtk_widget_show (widget); + gtk_menu_shell_append ((GtkMenuShell *) shell, widget); + } +} diff --git a/src/libaudgui/menu.h b/src/libaudgui/menu.h new file mode 100644 index 0000000..b62d26b --- /dev/null +++ b/src/libaudgui/menu.h @@ -0,0 +1,83 @@ +/* + * menu.h + * Copyright 2011-2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef AUDGUI_MENU_H +#define AUDGUI_MENU_H + +/* okay to use without audgui_init() */ + +#include <gtk/gtk.h> +#include <libaudcore/objects.h> + +struct AudguiMenuItem { + const char * name; + const char * icon; + unsigned key; + GdkModifierType mod; + + /* for normal items */ + void (* func) (); + + /* for toggle items */ + const char * csect; + const char * cname; + const char * hook; + + /* for submenus */ + ArrayRef<AudguiMenuItem> items; + + /* for custom submenus */ + GtkWidget * (* get_sub) (); + + /* for separators */ + bool sep; +}; + +constexpr AudguiMenuItem MenuCommand (const char * name, const char * icon, + unsigned key, GdkModifierType mod, void (* func) ()) + { return {name, icon, key, mod, func}; } + +constexpr AudguiMenuItem MenuToggle (const char * name, const char * icon, + unsigned key, GdkModifierType mod, const char * csect, const char * cname, + void (* func) () = 0, const char * hook = 0) + { return {name, icon, key, mod, func, csect, cname, hook}; } + +constexpr AudguiMenuItem MenuSub (const char * name, const char * icon, + ArrayRef<AudguiMenuItem> items) + { return {name, icon, 0, (GdkModifierType) 0, 0, 0, 0, 0, items}; } + +constexpr AudguiMenuItem MenuSub (const char * name, const char * icon, + GtkWidget * (* get_sub) ()) + { return {name, icon, 0, (GdkModifierType) 0, 0, 0, 0, 0, 0, get_sub}; } + +constexpr AudguiMenuItem MenuSep () + { return {0, 0, 0, (GdkModifierType) 0, 0, 0, 0, 0, 0, 0, true}; } + +/* use nullptr for domain to skip translation */ +GtkWidget * audgui_menu_item_new_with_domain (const AudguiMenuItem * item, + GtkAccelGroup * accel, const char * domain); + +void audgui_menu_init_with_domain (GtkWidget * shell, + ArrayRef<AudguiMenuItem> items, GtkAccelGroup * accel, + const char * domain); + +#define audgui_menu_item_new(i, a) audgui_menu_item_new_with_domain (i, a, PACKAGE) +#define audgui_menu_init(s, i, a) audgui_menu_init_with_domain (s, i, a, PACKAGE) + +#endif /* AUDGUI_MENU_H */ diff --git a/src/libaudgui/pixbufs.cc b/src/libaudgui/pixbufs.cc new file mode 100644 index 0000000..23d5fee --- /dev/null +++ b/src/libaudgui/pixbufs.cc @@ -0,0 +1,123 @@ +/* + * pixbufs.c + * Copyright 2010-2012 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gdk-pixbuf/gdk-pixbuf.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/drct.h> +#include <libaudcore/probe.h> +#include <libaudcore/runtime.h> + +#include "internal.h" +#include "libaudgui-gtk.h" + +static AudguiPixbuf current_pixbuf; + +EXPORT AudguiPixbuf audgui_pixbuf_fallback () +{ + static AudguiPixbuf fallback; + + if (! fallback) + { + GtkIconTheme * icon_theme = gtk_icon_theme_get_default (); + int icon_size = audgui_to_native_dpi (48); + + fallback.capture (gtk_icon_theme_load_icon (icon_theme, + "audio-x-generic", icon_size, (GtkIconLookupFlags) 0, nullptr)); + } + + return fallback.ref (); +} + +void audgui_pixbuf_uncache () +{ + current_pixbuf.clear (); +} + +EXPORT void audgui_pixbuf_scale_within (AudguiPixbuf & pixbuf, int size) +{ + int width = pixbuf.width (); + int height = pixbuf.height (); + + if (width <= size && height <= size) + return; + + if (width > height) + { + height = size * height / width; + width = size; + } + else + { + width = size * width / height; + height = size; + } + + if (width < 1) + width = 1; + if (height < 1) + height = 1; + + pixbuf.capture (gdk_pixbuf_scale_simple (pixbuf.get (), width, height, GDK_INTERP_BILINEAR)); +} + +EXPORT AudguiPixbuf audgui_pixbuf_request (const char * filename, bool * queued) +{ + AudArtPtr art = aud_art_request (filename, AUD_ART_DATA, queued); + + auto data = art.data (); + return data ? audgui_pixbuf_from_data (data->begin (), data->len ()) : AudguiPixbuf (); +} + +EXPORT AudguiPixbuf audgui_pixbuf_request_current (bool * queued) +{ + if (queued) + * queued = false; + + if (! current_pixbuf) + { + String filename = aud_drct_get_filename (); + if (filename) + current_pixbuf = audgui_pixbuf_request (filename, queued); + } + + return current_pixbuf.ref (); +} + +EXPORT AudguiPixbuf audgui_pixbuf_from_data (const void * data, int64_t size) +{ + GdkPixbuf * pixbuf = nullptr; + GdkPixbufLoader * loader = gdk_pixbuf_loader_new (); + GError * error = nullptr; + + if (gdk_pixbuf_loader_write (loader, (const unsigned char *) data, size, + & error) && gdk_pixbuf_loader_close (loader, & error)) + { + if ((pixbuf = gdk_pixbuf_loader_get_pixbuf (loader))) + g_object_ref (pixbuf); + } + else + { + AUDWARN ("While loading pixbuf: %s\n", error->message); + g_error_free (error); + } + + g_object_unref (loader); + return AudguiPixbuf (pixbuf); +} diff --git a/src/libaudgui/playlists.cc b/src/libaudgui/playlists.cc new file mode 100644 index 0000000..37c693a --- /dev/null +++ b/src/libaudgui/playlists.cc @@ -0,0 +1,227 @@ +/* + * playlists.c + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <string.h> +#include <gtk/gtk.h> + +#define AUD_GLIB_INTEGRATION +#include <libaudcore/audstrings.h> +#include <libaudcore/i18n.h> +#include <libaudcore/interface.h> +#include <libaudcore/playlist.h> +#include <libaudcore/runtime.h> +#include <libaudcore/tuple.h> +#include <libaudcore/vfs.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +struct ImportExportJob { + bool save; + Playlist list; + CharPtr filename; + GtkWidget * selector = nullptr; + GtkWidget * confirm = nullptr; + + ImportExportJob (bool save, Playlist list) : + save (save), list (list) {} +}; + +/* "destroy" callback; do not call directly */ +static void cleanup_job (void * data) +{ + ImportExportJob * job = (ImportExportJob *) data; + + CharPtr folder (gtk_file_chooser_get_current_folder_uri ((GtkFileChooser *) job->selector)); + if (folder) + aud_set_str ("audgui", "playlist_path", folder); + + if (job->confirm) + gtk_widget_destroy (job->confirm); + + delete job; +} + +static void finish_job (void * data) +{ + ImportExportJob * job = (ImportExportJob *) data; + + Playlist::GetMode mode = Playlist::Wait; + if (aud_get_bool ("metadata_on_play")) + mode = Playlist::NoWait; + + if (job->list.exists ()) + { + job->list.set_filename (job->filename); + + if (job->save) + job->list.save_to_file (job->filename, mode); + else + { + job->list.remove_all_entries (); + job->list.insert_entry (0, job->filename, Tuple (), false); + } + } + + gtk_widget_destroy (job->selector); +} + +static void confirm_overwrite (ImportExportJob * job) +{ + if (job->confirm) + gtk_widget_destroy (job->confirm); + + GtkWidget * button1 = audgui_button_new (_("_Overwrite"), "document-save", finish_job, job); + GtkWidget * button2 = audgui_button_new (_("_Cancel"), "process-stop", nullptr, nullptr); + + job->confirm = audgui_dialog_new (GTK_MESSAGE_QUESTION, + _("Confirm Overwrite"), str_printf (_("Overwrite %s?"), (const char *) job->filename), + button1, button2); + + g_signal_connect (job->confirm, "destroy", (GCallback) gtk_widget_destroyed, & job->confirm); + + gtk_widget_show_all (job->confirm); +} + +static void check_overwrite (void * data) +{ + ImportExportJob * job = (ImportExportJob *) data; + + job->filename = CharPtr (gtk_file_chooser_get_uri ((GtkFileChooser *) job->selector)); + if (! job->filename) + return; + + if (job->save && ! strchr (job->filename, '.')) + { + const char * default_ext = nullptr; + auto filter = gtk_file_chooser_get_filter ((GtkFileChooser *) job->selector); + + if (filter) + default_ext = (const char *) g_object_get_data ((GObject *) filter, "default-ext"); + + if (! default_ext) + { + aud_ui_show_error (_("Please type a filename extension or select a " + "format from the drop-down list.")); + return; + } + + job->filename.capture (g_strconcat (job->filename, ".", default_ext, nullptr)); + } + + if (job->save && VFSFile::test_file (job->filename, VFS_EXISTS)) + confirm_overwrite (job); + else + finish_job (data); +} + +static void set_format_filters (GtkWidget * selector) +{ + GtkFileFilter * filter; + + filter = gtk_file_filter_new (); + gtk_file_filter_set_name (filter, _("Select Format by Extension")); + gtk_file_filter_add_pattern (filter, "*"); + gtk_file_chooser_add_filter ((GtkFileChooser *) selector, filter); + + for (auto & format : Playlist::save_formats ()) + { + filter = gtk_file_filter_new (); + gtk_file_filter_set_name (filter, format.name); + + for (auto & ext : format.exts) + gtk_file_filter_add_pattern (filter, str_concat ({"*.", ext})); + + if (format.exts.len ()) + g_object_set_data_full ((GObject *) filter, "default-ext", + g_strdup (format.exts[0]), g_free); + + gtk_file_chooser_add_filter ((GtkFileChooser *) selector, filter); + } +} + +static void create_selector (ImportExportJob * job, const char * filename, const char * folder) +{ + const char * title, * verb, * icon; + GtkFileChooserAction action; + + if (job->save) + { + title = _("Export Playlist"); + verb = _("_Export"); + icon = "document-save"; + action = GTK_FILE_CHOOSER_ACTION_SAVE; + } + else + { + title = _("Import Playlist"); + verb = _("_Import"); + icon = "document-open"; + action = GTK_FILE_CHOOSER_ACTION_OPEN; + } + + job->selector = gtk_file_chooser_dialog_new (title, nullptr, action, nullptr, nullptr); + gtk_file_chooser_set_local_only ((GtkFileChooser *) job->selector, false); + + if (filename) + gtk_file_chooser_set_uri ((GtkFileChooser *) job->selector, filename); + else if (folder) + gtk_file_chooser_set_current_folder_uri ((GtkFileChooser *) job->selector, folder); + + GtkWidget * button1 = audgui_button_new (verb, icon, check_overwrite, job); + GtkWidget * button2 = audgui_button_new (_("_Cancel"), "process-stop", + (AudguiCallback) gtk_widget_destroy, job->selector); + + gtk_dialog_add_action_widget ((GtkDialog *) job->selector, button2, GTK_RESPONSE_NONE); + gtk_dialog_add_action_widget ((GtkDialog *) job->selector, button1, GTK_RESPONSE_NONE); + + gtk_widget_set_can_default (button1, true); + gtk_widget_grab_default (button1); + + if (job->save) + set_format_filters (job->selector); + + g_signal_connect_swapped (job->selector, "destroy", (GCallback) cleanup_job, job); + + gtk_widget_show_all (job->selector); +} + +static GtkWidget * start_job (bool save) +{ + auto list = Playlist::active_playlist (); + + String filename = list.get_filename (); + String folder = aud_get_str ("audgui", "playlist_path"); + + ImportExportJob * job = new ImportExportJob (save, list); + create_selector (job, filename, folder[0] ? (const char *) folder : nullptr); + + return job->selector; +} + +EXPORT void audgui_import_playlist () +{ + audgui_show_unique_window (AUDGUI_PLAYLIST_IMPORT_WINDOW, start_job (false)); +} + +EXPORT void audgui_export_playlist () +{ + audgui_show_unique_window (AUDGUI_PLAYLIST_EXPORT_WINDOW, start_job (true)); +} diff --git a/src/libaudgui/plugin-menu.cc b/src/libaudgui/plugin-menu.cc new file mode 100644 index 0000000..e5f3184 --- /dev/null +++ b/src/libaudgui/plugin-menu.cc @@ -0,0 +1,118 @@ +/* + * plugin-menu.c + * Copyright 2009-2011 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gtk/gtk.h> + +#include <libaudcore/i18n.h> +#include <libaudcore/interface.h> +#include <libaudcore/plugins.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" +#include "menu.h" + +static aud::array<AudMenuID, GList *> items; /* of AudguiMenuItem */ +static aud::array<AudMenuID, GtkWidget *> menus; + +static void configure_plugins () +{ + audgui_show_prefs_for_plugin_type (PluginType::General); +} + +static const AudguiMenuItem main_items[] = { + MenuCommand (N_("_Plugins ..."), 0, 0, (GdkModifierType) 0, configure_plugins), + MenuSep () +}; + +static void add_to_menu (GtkWidget * menu, const AudguiMenuItem * item) +{ + GtkWidget * widget = audgui_menu_item_new_with_domain (item, nullptr, nullptr); + g_object_set_data ((GObject *) widget, "func", (void *) item->func); + gtk_widget_show (widget); + gtk_menu_shell_append ((GtkMenuShell *) menu, widget); +} + +EXPORT GtkWidget * audgui_get_plugin_menu (AudMenuID id) +{ + if (! menus[id]) + { + menus[id] = gtk_menu_new (); + g_signal_connect (menus[id], "destroy", (GCallback) + gtk_widget_destroyed, & menus[id]); + + if (id == AudMenuID::Main) + audgui_menu_init (menus[id], main_items, nullptr); + + for (GList * node = items[id]; node; node = node->next) + add_to_menu (menus[id], (const AudguiMenuItem *) node->data); + } + + return menus[id]; +} + +EXPORT void audgui_plugin_menu_add (AudMenuID id, void (* func) (), + const char * name, const char * icon) +{ + AudguiMenuItem * item = g_slice_new0 (AudguiMenuItem); + item->name = name; + item->icon = icon; + item->func = func; + + items[id] = g_list_append (items[id], item); + + if (menus[id]) + add_to_menu (menus[id], item); +} + +static void remove_cb (GtkWidget * widget, void (* func) ()) +{ + if (g_object_get_data ((GObject *) widget, "func") == (void *) func) + gtk_widget_destroy (widget); +} + +EXPORT void audgui_plugin_menu_remove (AudMenuID id, void (* func) ()) +{ + if (menus[id]) + gtk_container_foreach ((GtkContainer *) menus[id], (GtkCallback) + remove_cb, (void *) func); + + GList * next; + for (GList * node = items[id]; node; node = next) + { + next = node->next; + + if (((AudguiMenuItem *) node->data)->func == func) + { + g_slice_free (AudguiMenuItem, node->data); + items[id] = g_list_delete_link (items[id], node); + } + } +} + +void plugin_menu_cleanup () +{ + for (AudMenuID id : aud::range<AudMenuID> ()) + { + g_warn_if_fail (! items[id]); + + if (menus[id]) + gtk_widget_destroy (menus[id]); + } +} diff --git a/src/libaudgui/plugin-prefs.cc b/src/libaudgui/plugin-prefs.cc new file mode 100644 index 0000000..ac27ae2 --- /dev/null +++ b/src/libaudgui/plugin-prefs.cc @@ -0,0 +1,191 @@ +/* + * plugin-prefs.c + * Copyright 2012-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <libaudcore/audstrings.h> +#include <libaudcore/i18n.h> +#include <libaudcore/plugin.h> +#include <libaudcore/plugins.h> +#include <libaudcore/preferences.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +static GList * about_windows; +static GList * config_windows; + +static int find_cb (GtkWidget * window, PluginHandle * plugin) +{ + return (g_object_get_data ((GObject *) window, "plugin-id") != plugin); +} + +static bool watch_cb (PluginHandle * plugin, void * window); + +/* window destroyed before plugin disabled */ +static void destroy_cb (GtkWidget * window, PluginHandle * plugin) +{ + GList * * list = & config_windows; + GList * node = g_list_find (* list, window); + + if (! node) + { + list = & about_windows; + node = g_list_find (* list, nullptr); /* set to nullptr by audgui_simple_message() */ + g_return_if_fail (node); + } + + aud_plugin_remove_watch (plugin, watch_cb, window); + + * list = g_list_delete_link (* list, node); +} + +/* plugin disabled before window destroyed */ +static bool watch_cb (PluginHandle * plugin, void * window) +{ + if (aud_plugin_get_enabled (plugin)) + return true; + + GList * * list = & about_windows; + GList * node = g_list_find (* list, window); + + if (! node) + { + list = & config_windows; + node = g_list_find (* list, window); + g_return_val_if_fail (node, false); + } + + g_signal_handlers_disconnect_by_func (window, (void *) destroy_cb, plugin); + gtk_widget_destroy ((GtkWidget *) window); + + * list = g_list_delete_link (* list, node); + + return false; +} + +EXPORT void audgui_show_plugin_about (PluginHandle * plugin) +{ + GList * node = g_list_find_custom (about_windows, plugin, (GCompareFunc) find_cb); + + if (node) + { + gtk_window_present ((GtkWindow *) node->data); + return; + } + + Plugin * header = (Plugin *) aud_plugin_get_header (plugin); + g_return_if_fail (header); + + const char * name = header->info.name; + const char * text = header->info.about; + if (! text) + return; + + if (header->info.domain) + { + name = dgettext (header->info.domain, name); + text = dgettext (header->info.domain, text); + } + + about_windows = node = g_list_prepend (about_windows, nullptr); + + audgui_simple_message ((GtkWidget * *) & node->data, GTK_MESSAGE_INFO, + str_printf (_("About %s"), name), text); + g_object_set_data ((GObject *) node->data, "plugin-id", plugin); + + g_signal_connect_after (node->data, "destroy", (GCallback) destroy_cb, plugin); + aud_plugin_add_watch (plugin, watch_cb, node->data); +} + +static void response_cb (GtkWidget * window, int response, const PluginPreferences * p) +{ + if (response == GTK_RESPONSE_OK && p->apply) + p->apply (); + + gtk_widget_destroy (window); +} + +static void cleanup_cb (GtkWidget * window, const PluginPreferences * p) +{ + if (p->cleanup) + p->cleanup (); +} + +EXPORT void audgui_show_plugin_prefs (PluginHandle * plugin) +{ + GList * node = g_list_find_custom (config_windows, plugin, (GCompareFunc) find_cb); + + if (node) + { + gtk_window_present ((GtkWindow *) node->data); + return; + } + + Plugin * header = (Plugin *) aud_plugin_get_header (plugin); + g_return_if_fail (header); + + const PluginPreferences * p = header->info.prefs; + if (! p) + return; + + if (p->init) + p->init (); + + const char * name = header->info.name; + if (header->info.domain) + name = dgettext (header->info.domain, name); + + GtkWidget * window = gtk_dialog_new (); + gtk_window_set_title ((GtkWindow *) window, str_printf (_("%s Settings"), name)); + + if (p->apply) + { + GtkWidget * button1 = audgui_button_new (_("_Set"), "system-run", nullptr, nullptr); + GtkWidget * button2 = audgui_button_new (_("_Cancel"), "process-stop", nullptr, nullptr); + gtk_dialog_add_action_widget ((GtkDialog *) window, button2, GTK_RESPONSE_CANCEL); + gtk_dialog_add_action_widget ((GtkDialog *) window, button1, GTK_RESPONSE_OK); + } + else + { + GtkWidget * button = audgui_button_new (_("_Close"), "window-close", nullptr, nullptr); + gtk_dialog_add_action_widget ((GtkDialog *) window, button, GTK_RESPONSE_CLOSE); + } + + GtkWidget * content = gtk_dialog_get_content_area ((GtkDialog *) window); + GtkWidget * box = gtk_vbox_new (false, 0); + audgui_create_widgets_with_domain (box, p->widgets, header->info.domain); + gtk_box_pack_start ((GtkBox *) content, box, true, true, 0); + + g_signal_connect (window, "response", (GCallback) response_cb, (void *) p); + g_signal_connect (window, "destroy", (GCallback) cleanup_cb, (void *) p); + + gtk_widget_show_all (window); + + g_object_set_data ((GObject *) window, "plugin-id", plugin); + config_windows = g_list_prepend (config_windows, window); + + g_signal_connect_after (window, "destroy", (GCallback) destroy_cb, plugin); + aud_plugin_add_watch (plugin, watch_cb, window); +} + +void plugin_prefs_cleanup () +{ + g_list_foreach (about_windows, (GFunc) gtk_widget_destroy, nullptr); + g_list_foreach (config_windows, (GFunc) gtk_widget_destroy, nullptr); +} diff --git a/src/libaudgui/plugin-view.cc b/src/libaudgui/plugin-view.cc new file mode 100644 index 0000000..8cf237e --- /dev/null +++ b/src/libaudgui/plugin-view.cc @@ -0,0 +1,250 @@ +/* + * plugin-view.c + * Copyright 2010-2012 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gtk/gtk.h> + +#include <libaudcore/i18n.h> +#include <libaudcore/plugin.h> +#include <libaudcore/plugins.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +enum { + PVIEW_COL_NODE, + PVIEW_COL_ENABLED, + PVIEW_COL_NAME, + PVIEW_COLS +}; + +struct Node { + PluginHandle * p; + GtkTreeModel * model; + GtkTreePath * path; +}; + +static PluginHandle * get_selected_plugin (GtkTreeView * tree) +{ + Node * n = nullptr; + + GtkTreeSelection * sel = gtk_tree_view_get_selection (tree); + + /* the treeview may not have a model yet */ + if (! sel) + return nullptr; + + GtkTreeModel * model; + GtkTreeIter iter; + if (gtk_tree_selection_get_selected (sel, & model, & iter)) + gtk_tree_model_get (model, & iter, PVIEW_COL_NODE, & n, -1); + + return n == nullptr ? nullptr : n->p; +} + +static void do_enable (GtkCellRendererToggle * cell, const char * path_str, + GtkTreeModel * model) +{ + GtkTreePath * path = gtk_tree_path_new_from_string (path_str); + GtkTreeIter iter; + gtk_tree_model_get_iter (model, & iter, path); + gtk_tree_path_free (path); + + Node * n = nullptr; + gboolean enabled; + gtk_tree_model_get (model, & iter, PVIEW_COL_NODE, & n, + PVIEW_COL_ENABLED, & enabled, -1); + g_return_if_fail (n != nullptr); + + aud_plugin_enable (n->p, ! enabled); +} + +static bool list_watcher (PluginHandle * p, void * data) +{ + auto n = (Node *) data; + + GtkTreeIter iter; + gtk_tree_model_get_iter (n->model, & iter, n->path); + gtk_list_store_set ((GtkListStore *) n->model, & iter, PVIEW_COL_ENABLED, + aud_plugin_get_enabled (n->p), -1); + + return true; +} + +static void add_to_list (GtkTreeModel * model, PluginHandle * p) +{ + Node * n = new Node; + + GtkTreeIter iter; + gtk_list_store_append ((GtkListStore *) model, & iter); + gtk_list_store_set ((GtkListStore *) model, & iter, PVIEW_COL_NODE, n, + PVIEW_COL_ENABLED, aud_plugin_get_enabled (p), PVIEW_COL_NAME, + aud_plugin_get_name (p), -1); + + n->p = p; + n->model = model; + n->path = gtk_tree_model_get_path (model, & iter); + + aud_plugin_add_watch (p, list_watcher, n); +} + +static void list_fill (GtkTreeView * tree, void * type) +{ + GtkTreeModel * model = (GtkTreeModel *) gtk_list_store_new (PVIEW_COLS, + G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_STRING); + gtk_tree_view_set_model (tree, model); + + GtkTreeViewColumn * col = gtk_tree_view_column_new (); + gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_GROW_ONLY); + gtk_tree_view_column_set_resizable (col, false); + gtk_tree_view_append_column (tree, col); + + GtkCellRenderer * rend = gtk_cell_renderer_toggle_new (); + g_signal_connect (rend, "toggled", (GCallback) do_enable, model); + gtk_tree_view_column_pack_start (col, rend, false); + gtk_tree_view_column_set_attributes (col, rend, "active", PVIEW_COL_ENABLED, + nullptr); + + col = gtk_tree_view_column_new (); + gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_expand (col, true); + gtk_tree_view_column_set_resizable (col, false); + gtk_tree_view_append_column (tree, col); + + rend = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (col, rend, false); + gtk_tree_view_column_set_attributes (col, rend, "text", PVIEW_COL_NAME, nullptr); + + for (PluginHandle * plugin : aud_plugin_list (aud::from_ptr<PluginType> (type))) + add_to_list (model, plugin); +} + +static void list_destroy (GtkTreeView * tree) +{ + GtkTreeModel * model = gtk_tree_view_get_model (tree); + if (model == nullptr) + return; + + GtkTreeIter iter; + if (gtk_tree_model_get_iter_first (model, & iter)) + { + do + { + Node * n = nullptr; + gtk_tree_model_get (model, & iter, PVIEW_COL_NODE, & n, -1); + g_return_if_fail (n != nullptr); + + aud_plugin_remove_watch (n->p, list_watcher, n); + gtk_tree_path_free (n->path); + delete n; + } + while (gtk_tree_model_iter_next (model, & iter)); + } + + g_object_unref ((GObject *) model); +} + +static bool watcher (PluginHandle * p, void * b) +{ + bool is_about = GPOINTER_TO_INT (g_object_get_data ((GObject *) b, "is_about")); + + if (is_about) + gtk_widget_set_sensitive ((GtkWidget *) b, + aud_plugin_has_about (p) && aud_plugin_get_enabled (p)); + else + gtk_widget_set_sensitive ((GtkWidget *) b, + aud_plugin_has_configure (p) && aud_plugin_get_enabled (p)); + + return true; +} + +static void button_update (GtkTreeView * tree, GtkWidget * b) +{ + PluginHandle * p = (PluginHandle *) g_object_steal_data ((GObject *) b, "plugin"); + if (p != nullptr) + aud_plugin_remove_watch (p, watcher, b); + + p = get_selected_plugin (tree); + if (p != nullptr) + { + g_object_set_data ((GObject *) b, "plugin", p); + watcher (p, b); + aud_plugin_add_watch (p, watcher, b); + } + else + gtk_widget_set_sensitive (b, false); +} + +static void do_config (void * tree) +{ + PluginHandle * plugin = get_selected_plugin ((GtkTreeView *) tree); + g_return_if_fail (plugin != nullptr); + audgui_show_plugin_prefs (plugin); +} + +static void do_about (void * tree) +{ + PluginHandle * plugin = get_selected_plugin ((GtkTreeView *) tree); + g_return_if_fail (plugin != nullptr); + audgui_show_plugin_about (plugin); +} + +static void button_destroy (GtkWidget * b) +{ + PluginHandle * p = (PluginHandle *) g_object_steal_data ((GObject *) b, "plugin"); + if (p != nullptr) + aud_plugin_remove_watch (p, watcher, b); +} + +GtkWidget * plugin_view_new (PluginType type) +{ + GtkWidget * vbox = gtk_vbox_new (false, 6); + gtk_container_set_border_width ((GtkContainer *) vbox, 6); + + GtkWidget * scrolled = gtk_scrolled_window_new (nullptr, nullptr); + gtk_box_pack_start ((GtkBox *) vbox, scrolled, true, true, 0); + gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolled, + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, GTK_SHADOW_IN); + + GtkWidget * tree = gtk_tree_view_new (); + gtk_container_add ((GtkContainer *) scrolled, tree); + gtk_tree_view_set_headers_visible ((GtkTreeView *) tree, false); + g_signal_connect (tree, "realize", (GCallback) list_fill, aud::to_ptr (type)); + g_signal_connect (tree, "destroy", (GCallback) list_destroy, nullptr); + + GtkWidget * hbox = gtk_hbox_new (false, 6); + gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 0); + + GtkWidget * config = audgui_button_new (_("_Settings"), "preferences-system", do_config, tree); + gtk_box_pack_start ((GtkBox *) hbox, config, false, false, 0); + gtk_widget_set_sensitive (config, false); + g_object_set_data ((GObject *) config, "is_about", GINT_TO_POINTER (false)); + g_signal_connect (tree, "cursor-changed", (GCallback) button_update, config); + g_signal_connect (config, "destroy", (GCallback) button_destroy, nullptr); + + GtkWidget * about = audgui_button_new (_("_About"), "help-about", do_about, tree); + gtk_box_pack_start ((GtkBox *) hbox, about, false, false, 0); + gtk_widget_set_sensitive (about, false); + g_object_set_data ((GObject *) about, "is_about", GINT_TO_POINTER (true)); + g_signal_connect (tree, "cursor-changed", (GCallback) button_update, about); + g_signal_connect (about, "destroy", (GCallback) button_destroy, nullptr); + + return vbox; +} diff --git a/src/libaudgui/prefs-widget.cc b/src/libaudgui/prefs-widget.cc new file mode 100644 index 0000000..7fba25f --- /dev/null +++ b/src/libaudgui/prefs-widget.cc @@ -0,0 +1,644 @@ +/* + * prefs-widget.c + * Copyright 2007-2014 Tomasz Moń, Ariadne Conill, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <string.h> +#include <gtk/gtk.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/preferences.h> +#include <libaudcore/runtime.h> + +#include "libaudgui-gtk.h" + +static void widget_changed (GtkWidget * widget, const PreferencesWidget * w) +{ + switch (w->type) + { + case PreferencesWidget::CheckButton: + { + bool set = gtk_toggle_button_get_active ((GtkToggleButton *) widget); + w->cfg.set_bool (set); + + auto child = (GtkWidget *) g_object_get_data ((GObject *) widget, "child"); + if (child) + gtk_widget_set_sensitive (child, set); + + break; + } + + case PreferencesWidget::RadioButton: + { + bool set = gtk_toggle_button_get_active ((GtkToggleButton *) widget); + if (set) + w->cfg.set_int (w->data.radio_btn.value); + + auto child = (GtkWidget *) g_object_get_data ((GObject *) widget, "child"); + if (child) + gtk_widget_set_sensitive (child, set); + + break; + } + + case PreferencesWidget::SpinButton: + if (w->cfg.type == WidgetConfig::Int) + w->cfg.set_int (gtk_spin_button_get_value_as_int ((GtkSpinButton *) widget)); + else if (w->cfg.type == WidgetConfig::Float) + w->cfg.set_float (gtk_spin_button_get_value ((GtkSpinButton *) widget)); + + break; + + case PreferencesWidget::FontButton: + w->cfg.set_string (gtk_font_button_get_font_name ((GtkFontButton *) widget)); + break; + + case PreferencesWidget::Entry: + w->cfg.set_string (gtk_entry_get_text ((GtkEntry *) widget)); + break; + + case PreferencesWidget::FileEntry: + { + String uri = audgui_file_entry_get_uri (widget); + w->cfg.set_string (uri ? uri : ""); + break; + } + + case PreferencesWidget::ComboBox: + { + auto items = (const ComboItem *) g_object_get_data ((GObject *) widget, "comboitems"); + int idx = gtk_combo_box_get_active ((GtkComboBox *) widget); + + if (w->cfg.type == WidgetConfig::Int) + w->cfg.set_int (items[idx].num); + else if (w->cfg.type == WidgetConfig::String) + w->cfg.set_string (items[idx].str); + + break; + } + + default: + break; + } +} + +static void combobox_update (GtkWidget * combobox, const PreferencesWidget * widget); + +static void widget_update (void *, void * widget) +{ + auto w = (const PreferencesWidget *) g_object_get_data ((GObject *) widget, "prefswidget"); + + g_signal_handlers_block_by_func (widget, (void *) widget_changed, (void *) w); + + switch (w->type) + { + case PreferencesWidget::CheckButton: + gtk_toggle_button_set_active ((GtkToggleButton *) widget, w->cfg.get_bool ()); + break; + + case PreferencesWidget::RadioButton: + if (w->cfg.get_int () == w->data.radio_btn.value) + gtk_toggle_button_set_active ((GtkToggleButton *) widget, true); + + break; + + case PreferencesWidget::SpinButton: + if (w->cfg.type == WidgetConfig::Int) + gtk_spin_button_set_value ((GtkSpinButton *) widget, w->cfg.get_int ()); + else if (w->cfg.type == WidgetConfig::Float) + gtk_spin_button_set_value ((GtkSpinButton *) widget, w->cfg.get_float ()); + + break; + + case PreferencesWidget::FontButton: + gtk_font_button_set_font_name ((GtkFontButton *) widget, w->cfg.get_string ()); + break; + + case PreferencesWidget::Entry: + gtk_entry_set_text ((GtkEntry *) widget, w->cfg.get_string ()); + break; + + case PreferencesWidget::FileEntry: + audgui_file_entry_set_uri ((GtkWidget *) widget, w->cfg.get_string ()); + break; + + case PreferencesWidget::ComboBox: + combobox_update ((GtkWidget *) widget, w); + break; + + default: + break; + } + + g_signal_handlers_unblock_by_func (widget, (void *) widget_changed, (void *) w); +} + +static void widget_unhook (GtkWidget * widget, const PreferencesWidget * w) +{ + hook_dissociate (w->cfg.hook, widget_update, widget); +} + +static void widget_init (GtkWidget * widget, const PreferencesWidget * w) +{ + g_object_set_data ((GObject *) widget, "prefswidget", (void *) w); + + widget_update (nullptr, widget); + + switch (w->type) + { + case PreferencesWidget::CheckButton: + case PreferencesWidget::RadioButton: + g_signal_connect (widget, "toggled", (GCallback) widget_changed, (void *) w); + break; + + case PreferencesWidget::SpinButton: + g_signal_connect (widget, "value_changed", (GCallback) widget_changed, (void *) w); + break; + + case PreferencesWidget::FontButton: + g_signal_connect (widget, "font_set", (GCallback) widget_changed, (void *) w); + break; + + case PreferencesWidget::Entry: + case PreferencesWidget::FileEntry: + case PreferencesWidget::ComboBox: + g_signal_connect (widget, "changed", (GCallback) widget_changed, (void *) w); + break; + + default: + break; + } + + if (w->cfg.hook) + { + hook_associate (w->cfg.hook, widget_update, widget); + g_signal_connect (widget, "destroy", (GCallback) widget_unhook, (void *) w); + } +} + +/* WIDGET_LABEL */ + +static void create_label (const PreferencesWidget * widget, GtkWidget * * label, + GtkWidget * * icon, const char * domain) +{ + * label = gtk_label_new_with_mnemonic (dgettext (domain, widget->label)); + gtk_label_set_use_markup ((GtkLabel *) * label, true); + gtk_label_set_line_wrap ((GtkLabel *) * label, true); + gtk_misc_set_alignment ((GtkMisc *) * label, 0, 0.5); +} + +/* WIDGET_SPIN_BTN */ + +static void create_spin_button (const PreferencesWidget * widget, + GtkWidget * * label_pre, GtkWidget * * spin_btn, GtkWidget * * label_past, + const char * domain) +{ + if (widget->label) + { + * label_pre = gtk_label_new (dgettext (domain, widget->label)); + gtk_misc_set_alignment ((GtkMisc *) * label_pre, 1, 0.5); + } + + * spin_btn = gtk_spin_button_new_with_range (widget->data.spin_btn.min, + widget->data.spin_btn.max, widget->data.spin_btn.step); + + if (widget->data.spin_btn.right_label) + { + * label_past = gtk_label_new (dgettext (domain, widget->data.spin_btn.right_label)); + gtk_misc_set_alignment ((GtkMisc *) * label_past, 0, 0.5); + } + + widget_init (* spin_btn, widget); +} + +/* WIDGET_FONT_BTN */ + +void create_font_btn (const PreferencesWidget * widget, GtkWidget * * label, + GtkWidget * * font_btn, const char * domain) +{ + * font_btn = gtk_font_button_new (); + gtk_font_button_set_use_font ((GtkFontButton *) * font_btn, true); + gtk_font_button_set_use_size ((GtkFontButton *) * font_btn, true); + + if (widget->label) + { + * label = gtk_label_new (dgettext (domain, widget->label)); + gtk_misc_set_alignment ((GtkMisc *) * label, 1, 0.5); + } + + if (widget->data.font_btn.title) + gtk_font_button_set_title ((GtkFontButton *) * font_btn, + dgettext (domain, widget->data.font_btn.title)); + + widget_init (* font_btn, widget); +} + +/* WIDGET_ENTRY */ + +static void create_entry (const PreferencesWidget * widget, GtkWidget * * label, + GtkWidget * * entry, const char * domain) +{ + * entry = gtk_entry_new (); + gtk_entry_set_visibility ((GtkEntry *) * entry, ! widget->data.entry.password); + + if (widget->label) + { + * label = gtk_label_new (dgettext (domain, widget->label)); + gtk_misc_set_alignment ((GtkMisc *) * label, 1, 0.5); + } + + widget_init (* entry, widget); +} + +/* WIDGET_FILE_ENTRY */ + +static void create_file_entry (const PreferencesWidget * widget, + GtkWidget * * label, GtkWidget * * entry, const char * domain) +{ + switch (widget->data.file_entry.mode) + { + case FileSelectMode::File: + * entry = audgui_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN, _("Choose File")); + break; + + case FileSelectMode::Folder: + * entry = audgui_file_entry_new (GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, _("Choose Folder")); + break; + } + + if (widget->label) + { + * label = gtk_label_new (dgettext (domain, widget->label)); + gtk_misc_set_alignment ((GtkMisc *) * label, 1, 0.5); + } + + widget_init (* entry, widget); +} + +/* WIDGET_COMBO_BOX */ + +static void combobox_update (GtkWidget * combobox, const PreferencesWidget * widget) +{ + auto domain = (const char *) g_object_get_data ((GObject *) combobox, "combodomain"); + + ArrayRef<ComboItem> items = widget->data.combo.elems; + if (widget->data.combo.fill) + items = widget->data.combo.fill (); + + g_object_set_data ((GObject *) combobox, "comboitems", (void *) items.data); + + /* no gtk_combo_box_text_clear()? */ + gtk_list_store_clear ((GtkListStore *) gtk_combo_box_get_model ((GtkComboBox *) combobox)); + + for (const ComboItem & item : items) + gtk_combo_box_text_append_text ((GtkComboBoxText *) combobox, + dgettext (domain, item.label)); + + if (widget->cfg.type == WidgetConfig::Int) + { + int num = widget->cfg.get_int (); + + for (int i = 0; i < items.len; i ++) + { + if (items.data[i].num == num) + { + gtk_combo_box_set_active ((GtkComboBox *) combobox, i); + break; + } + } + } + else if (widget->cfg.type == WidgetConfig::String) + { + String str = widget->cfg.get_string (); + + for (int i = 0; i < items.len; i ++) + { + if (! strcmp_safe (items.data[i].str, str)) + { + gtk_combo_box_set_active ((GtkComboBox *) combobox, i); + break; + } + } + } +} + +static void create_cbox (const PreferencesWidget * widget, GtkWidget * * label, + GtkWidget * * combobox, const char * domain) +{ + * combobox = gtk_combo_box_text_new (); + + if (widget->label) + { + * label = gtk_label_new (dgettext (domain, widget->label)); + gtk_misc_set_alignment ((GtkMisc *) * label, 1, 0.5); + } + + g_object_set_data ((GObject *) * combobox, "combodomain", (void *) domain); + widget_init (* combobox, widget); +} + +/* WIDGET_TABLE */ + +static void fill_table (GtkWidget * table, + ArrayRef<PreferencesWidget> widgets, const char * domain) +{ + for (const PreferencesWidget & w : widgets) + { + GtkWidget * widget_left = nullptr, * widget_middle = nullptr, * widget_right = nullptr; + GtkAttachOptions middle_policy = (GtkAttachOptions) (GTK_FILL); + + switch (w.type) + { + case PreferencesWidget::SpinButton: + create_spin_button (& w, & widget_left, + & widget_middle, & widget_right, domain); + break; + + case PreferencesWidget::Label: + create_label (& w, & widget_middle, & widget_left, domain); + break; + + case PreferencesWidget::FontButton: + create_font_btn (& w, & widget_left, & widget_middle, domain); + break; + + case PreferencesWidget::Entry: + create_entry (& w, & widget_left, & widget_middle, domain); + middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL); + break; + + case PreferencesWidget::FileEntry: + create_file_entry (& w, & widget_left, & widget_middle, domain); + middle_policy = (GtkAttachOptions) (GTK_EXPAND | GTK_FILL); + break; + + case PreferencesWidget::ComboBox: + create_cbox (& w, & widget_left, & widget_middle, domain); + break; + + default: + break; + } + + int i = & w - widgets.data; + + if (widget_left) + gtk_table_attach ((GtkTable *) table, widget_left, 0, 1, i, i + 1, + GTK_FILL, GTK_FILL, 0, 0); + + if (widget_middle) + gtk_table_attach ((GtkTable *) table, widget_middle, 1, 2, i, i + 1, + middle_policy, GTK_FILL, 0, 0); + + if (widget_right) + gtk_table_attach ((GtkTable *) table, widget_right, 2, 3, i, i + 1, + GTK_FILL, GTK_FILL, 0, 0); + } +} + +/* ALL WIDGETS */ + +/* box: a GtkBox */ +void audgui_create_widgets_with_domain (GtkWidget * box, + ArrayRef<PreferencesWidget> widgets, const char * domain) +{ + GtkWidget * widget = nullptr, * child_box = nullptr; + bool disable_child = false; + GSList * radio_btn_group[2] = {}; + + int indent = 0; + int spacing = 0; + + for (const PreferencesWidget & w : widgets) + { + GtkWidget * label = nullptr; + + if (widget && w.child) + { + if (! child_box) + { + child_box = gtk_vbox_new (false, 0); + g_object_set_data ((GObject *) widget, "child", child_box); + + GtkWidget * alignment = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_box_pack_start ((GtkBox *) box, alignment, false, false, 0); + gtk_alignment_set_padding ((GtkAlignment *) alignment, 0, 0, 12, 0); + gtk_container_add ((GtkContainer *) alignment, child_box); + + if (disable_child) + gtk_widget_set_sensitive (child_box, false); + } + } + else + child_box = nullptr; + + GtkWidget * alignment = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_alignment_set_padding ((GtkAlignment *) alignment, spacing, 0, indent, 0); + gtk_box_pack_start ((GtkBox *) (child_box ? child_box : box), alignment, false, false, 0); + + widget = nullptr; + disable_child = false; + + if (w.type != PreferencesWidget::RadioButton) + radio_btn_group[w.child] = nullptr; + + if (! w.child) + radio_btn_group[true] = nullptr; + + switch (w.type) + { + case PreferencesWidget::Button: + widget = audgui_button_new (dgettext (domain, w.label), + w.data.button.icon, (AudguiCallback) w.data.button.callback, nullptr); + break; + + case PreferencesWidget::CheckButton: + widget = gtk_check_button_new_with_mnemonic (dgettext (domain, w.label)); + disable_child = ! w.cfg.get_bool (); + widget_init (widget, & w); + break; + + case PreferencesWidget::Label: + { + if (strstr (w.label, "<b>")) + { + /* headings get double spacing and no indent */ + gtk_alignment_set_padding ((GtkAlignment *) alignment, 2 * spacing, 0, 0, 0); + + /* set indent for items below the heading */ + indent = 12; + } + + GtkWidget * icon = nullptr; + create_label (& w, & label, & icon, domain); + + if (icon) + { + widget = gtk_hbox_new (false, 6); + gtk_box_pack_start ((GtkBox *) widget, icon, false, false, 0); + gtk_box_pack_start ((GtkBox *) widget, label, false, false, 0); + } + else + widget = label; + + break; + } + + case PreferencesWidget::RadioButton: + widget = gtk_radio_button_new_with_mnemonic + (radio_btn_group[w.child], dgettext (domain, w.label)); + radio_btn_group[w.child] = gtk_radio_button_get_group ((GtkRadioButton *) widget); + disable_child = (w.cfg.get_int () != w.data.radio_btn.value); + widget_init (widget, & w); + break; + + case PreferencesWidget::SpinButton: + { + widget = gtk_hbox_new (false, 6); + + GtkWidget * label_pre = nullptr, * spin_btn = nullptr, * label_past = nullptr; + create_spin_button (& w, & label_pre, & spin_btn, & label_past, domain); + + if (label_pre) + gtk_box_pack_start ((GtkBox *) widget, label_pre, false, false, 0); + if (spin_btn) + gtk_box_pack_start ((GtkBox *) widget, spin_btn, false, false, 0); + if (label_past) + gtk_box_pack_start ((GtkBox *) widget, label_past, false, false, 0); + + break; + } + + case PreferencesWidget::CustomGTK: + if (w.data.populate) + widget = (GtkWidget *) w.data.populate (); + + break; + + case PreferencesWidget::FontButton: + { + widget = gtk_hbox_new (false, 6); + + GtkWidget * font_btn = nullptr; + create_font_btn (& w, & label, & font_btn, domain); + + if (label) + gtk_box_pack_start ((GtkBox *) widget, label, false, false, 0); + if (font_btn) + gtk_box_pack_start ((GtkBox *) widget, font_btn, false, false, 0); + + break; + } + + case PreferencesWidget::Table: + widget = gtk_table_new (0, 0, false); + gtk_table_set_col_spacings ((GtkTable *) widget, 6); + gtk_table_set_row_spacings ((GtkTable *) widget, 6); + + fill_table (widget, w.data.table.widgets, domain); + + break; + + case PreferencesWidget::Entry: + case PreferencesWidget::FileEntry: + { + widget = gtk_hbox_new (false, 6); + + GtkWidget * entry = nullptr; + + if (w.type == PreferencesWidget::FileEntry) + create_file_entry (& w, & label, & entry, domain); + else + create_entry (& w, & label, & entry, domain); + + if (label) + gtk_box_pack_start ((GtkBox *) widget, label, false, false, 0); + if (entry) + gtk_box_pack_start ((GtkBox *) widget, entry, true, true, 0); + + break; + } + + case PreferencesWidget::ComboBox: + { + widget = gtk_hbox_new (false, 6); + + GtkWidget * combo = nullptr; + create_cbox (& w, & label, & combo, domain); + + if (label) + gtk_box_pack_start ((GtkBox *) widget, label, false, false, 0); + if (combo) + gtk_box_pack_start ((GtkBox *) widget, combo, false, false, 0); + + break; + } + + case PreferencesWidget::Box: + if (w.data.box.horizontal) + widget = gtk_hbox_new (false, 6); + else + widget = gtk_vbox_new (false, 0); + + audgui_create_widgets_with_domain (widget, w.data.box.widgets, domain); + + if (w.data.box.frame) + { + GtkWidget * frame = gtk_frame_new (dgettext (domain, w.label)); + gtk_container_add ((GtkContainer *) frame, widget); + widget = frame; + } + + break; + + case PreferencesWidget::Notebook: + gtk_alignment_set_padding ((GtkAlignment *) alignment, 0, 0, 0, 0); + + widget = gtk_notebook_new (); + + for (const NotebookTab & tab : w.data.notebook.tabs) + { + GtkWidget * vbox = gtk_vbox_new (false, 0); + gtk_container_set_border_width ((GtkContainer *) vbox, 6); + + audgui_create_widgets_with_domain (vbox, tab.widgets, domain); + + gtk_notebook_append_page ((GtkNotebook *) widget, vbox, + gtk_label_new (dgettext (domain, tab.name))); + } + + break; + + case PreferencesWidget::Separator: + widget = w.data.separator.horizontal ? + gtk_hseparator_new () : gtk_vseparator_new (); + break; + + default: + break; + } + + if (widget) + gtk_container_add ((GtkContainer *) alignment, widget); + + /* wait till after first widget to set item spacing */ + if (gtk_orientable_get_orientation ((GtkOrientable *) box) == GTK_ORIENTATION_VERTICAL) + spacing = 6; + } +} diff --git a/src/libaudgui/prefs-window.cc b/src/libaudgui/prefs-window.cc new file mode 100644 index 0000000..aa81891 --- /dev/null +++ b/src/libaudgui/prefs-window.cc @@ -0,0 +1,949 @@ +/* + * prefs-window.cc + * Copyright 2006-2014 Ariadne Conill, Tomasz Moń, Michael Färber, and + * John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <string.h> + +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/drct.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/playlist.h> +#include <libaudcore/plugin.h> +#include <libaudcore/plugins.h> +#include <libaudcore/preferences.h> +#include <libaudcore/runtime.h> + +#include "libguess/libguess.h" + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +enum CategoryViewCols { + CATEGORY_VIEW_COL_ICON, + CATEGORY_VIEW_COL_NAME, + CATEGORY_VIEW_N_COLS +}; + +struct Category { + const char * icon; + const char * name; +}; + +struct PluginCategory { + PluginType type; + const char * name; +}; + +struct TitleFieldTag { + const char * name; + const char * tag; +}; + +static const char aud_version_string[] = + "<span size='small'>Audacious " VERSION " (" BUILDSTAMP ")</span>"; + +static GtkWidget * prefswin; +static GtkWidget * category_treeview, * category_notebook, * plugin_notebook; +static GtkWidget * titlestring_entry; + +enum { + CATEGORY_APPEARANCE = 0, + CATEGORY_AUDIO, + CATEGORY_NETWORK, + CATEGORY_PLAYLIST, + CATEGORY_SONG_INFO, + CATEGORY_PLUGINS, + CATEGORY_ADVANCED +}; + +/* keep this in sync with the list in load_fallback_icons (init.cc) */ +static const Category categories[] = { + { "applications-graphics", N_("Appearance") }, + { "audio-volume-medium", N_("Audio") }, + { "applications-internet", N_("Network") }, + { "audio-x-generic", N_("Playlist")} , + { "dialog-information", N_("Song Info") }, + { "applications-system", N_("Plugins") }, + { "preferences-system", N_("Advanced") } +}; + +static const PluginCategory plugin_categories[] = { + { PluginType::General, N_("General") }, + { PluginType::Effect, N_("Effect") }, + { PluginType::Vis, N_("Visualization") }, + { PluginType::Input, N_("Input") }, + { PluginType::Playlist, N_("Playlist") }, + { PluginType::Transport, N_("Transport") } +}; + +static const TitleFieldTag title_field_tags[] = { + { N_("Artist") , "${artist}" }, + { N_("Album") , "${album}" }, + { N_("Album artist"), "${album-artist}" }, + { N_("Title") , "${title}" }, + { N_("Track number"), "${track-number}" }, + { N_("Genre") , "${genre}" }, + { N_("File name") , "${file-name}" }, + { N_("File path") , "${file-path}" }, + { N_("Date") , "${date}" }, + { N_("Description") , "${description}" }, + { N_("Year") , "${year}" }, + { N_("Comment") , "${comment}" }, + { N_("Codec") , "${codec}" }, + { N_("Quality") , "${quality}" } +}; + +static const ComboItem chardet_detector_presets[] = { + ComboItem (N_("None"), ""), + ComboItem (N_("Arabic"), GUESS_REGION_AR), + ComboItem (N_("Baltic"), GUESS_REGION_BL), + ComboItem (N_("Chinese"), GUESS_REGION_CN), + ComboItem (N_("Greek"), GUESS_REGION_GR), + ComboItem (N_("Hebrew"), GUESS_REGION_HW), + ComboItem (N_("Japanese"), GUESS_REGION_JP), + ComboItem (N_("Korean"), GUESS_REGION_KR), + ComboItem (N_("Polish"), GUESS_REGION_PL), + ComboItem (N_("Russian"), GUESS_REGION_RU), + ComboItem (N_("Taiwanese"), GUESS_REGION_TW), + ComboItem (N_("Turkish"), GUESS_REGION_TR) +}; + +static const ComboItem bitdepth_elements[] = { + ComboItem (N_("Automatic"), -1), + ComboItem ("16", 16), + ComboItem ("24", 24), + ComboItem ("32", 32), + ComboItem (N_("Floating point"), 0) +}; + +static const ComboItem record_elements[] = { + ComboItem (N_("As decoded"), (int) OutputStream::AsDecoded), + ComboItem (N_("After applying ReplayGain"), (int) OutputStream::AfterReplayGain), + ComboItem (N_("After applying effects"), (int) OutputStream::AfterEffects), + ComboItem (N_("After applying equalization"), (int) OutputStream::AfterEqualizer) +}; + +static const ComboItem replaygainmode_elements[] = { + ComboItem (N_("Track"), (int) ReplayGainMode::Track), + ComboItem (N_("Album"), (int) ReplayGainMode::Album), + ComboItem (N_("Based on shuffle"), (int) ReplayGainMode::Automatic) +}; + +static Index<ComboItem> iface_combo_elements; +static int iface_combo_selected; +static GtkWidget * iface_prefs_box; + +static ArrayRef<ComboItem> iface_combo_fill (); +static void iface_combo_changed (); +static void * iface_create_prefs_box (); + +static const PreferencesWidget appearance_page_widgets[] = { + WidgetCombo (N_("Interface:"), + WidgetInt (iface_combo_selected, iface_combo_changed), + {0, iface_combo_fill}), + WidgetSeparator ({true}), + WidgetCustomGTK (iface_create_prefs_box) +}; + +static Index<ComboItem> output_combo_elements; +static int output_combo_selected; +static GtkWidget * output_config_button; +static GtkWidget * output_about_button; + +static ArrayRef<ComboItem> output_combo_fill (); +static void output_combo_changed (); +static void * output_create_config_button (); +static void * output_create_about_button (); +static void output_bit_depth_changed (); + +static const PreferencesWidget output_combo_widgets[] = { + WidgetCombo (N_("Output plugin:"), + WidgetInt (output_combo_selected, output_combo_changed, "audgui update output combo"), + {0, output_combo_fill}), + WidgetCustomGTK (output_create_config_button), + WidgetCustomGTK (output_create_about_button) +}; + +static GtkWidget * record_checkbox; +static GtkWidget * record_config_button; +static GtkWidget * record_about_button; + +static void * record_create_checkbox (); +static void * record_create_config_button (); +static void * record_create_about_button (); + +static const PreferencesWidget record_buttons[] = { + WidgetCustomGTK (record_create_config_button), + WidgetCustomGTK (record_create_about_button) +}; + +static const PreferencesWidget gain_table[] = { + WidgetSpin (N_("Amplify all files:"), + WidgetFloat (0, "replay_gain_preamp"), + {-15, 15, 0.1, N_("dB")}), + WidgetSpin (N_("Amplify untagged files:"), + WidgetFloat (0, "default_gain"), + {-15, 15, 0.1, N_("dB")}) +}; + +static const PreferencesWidget audio_page_widgets[] = { + WidgetLabel (N_("<b>Output Settings</b>")), + WidgetBox ({{output_combo_widgets}, true}), + WidgetCombo (N_("Bit depth:"), + WidgetInt (0, "output_bit_depth", output_bit_depth_changed), + {{bitdepth_elements}}), + WidgetSpin (N_("Buffer size:"), + WidgetInt (0, "output_buffer_size"), + {100, 10000, 1000, N_("ms")}), + WidgetCheck (N_("Soft clipping"), + WidgetBool (0, "soft_clipping")), + WidgetCheck (N_("Use software volume control (not recommended)"), + WidgetBool (0, "software_volume_control")), + WidgetLabel (N_("<b>Recording Settings</b>")), + WidgetCustomGTK (record_create_checkbox), + WidgetBox ({{record_buttons}, true}, + WIDGET_CHILD), + WidgetCombo (N_("Record stream:"), + WidgetInt (0, "record_stream"), + {{record_elements}}), + WidgetLabel (N_("<b>ReplayGain</b>")), + WidgetCheck (N_("Enable ReplayGain"), + WidgetBool (0, "enable_replay_gain")), + WidgetCombo (N_("Mode:"), + WidgetInt (0, "replay_gain_mode"), + {{replaygainmode_elements}}, + WIDGET_CHILD), + WidgetCheck (N_("Prevent clipping (recommended)"), + WidgetBool (0, "enable_clipping_prevention"), + WIDGET_CHILD), + WidgetTable ({{gain_table}}, + WIDGET_CHILD) +}; + +static const PreferencesWidget proxy_host_port_elements[] = { + WidgetEntry (N_("Proxy hostname:"), + WidgetString (0, "proxy_host")), + WidgetEntry (N_("Proxy port:"), + WidgetString (0, "proxy_port")) +}; + +static const PreferencesWidget proxy_auth_elements[] = { + WidgetEntry (N_("Proxy username:"), + WidgetString (0, "proxy_user")), + WidgetEntry (N_("Proxy password:"), + WidgetString (0, "proxy_pass"), + {true}) +}; + +static const PreferencesWidget connectivity_page_widgets[] = { + WidgetLabel (N_("<b>Network Settings</b>")), + WidgetSpin (N_("Buffer size:"), + WidgetInt (0, "net_buffer_kb"), + {16, 1024, 16, N_("KiB")}), + WidgetLabel (N_("<b>Proxy Configuration</b>")), + WidgetCheck (N_("Enable proxy usage"), + WidgetBool (0, "use_proxy")), + WidgetTable ({{proxy_host_port_elements}}, + WIDGET_CHILD), + WidgetCheck (N_("Use authentication with proxy"), + WidgetBool (0, "use_proxy_auth")), + WidgetTable ({{proxy_auth_elements}}, + WIDGET_CHILD), + WidgetCheck (N_("Use SOCKS proxy"), + WidgetBool (0, "socks_proxy")), + WidgetRadio (N_("SOCKS v4a"), + WidgetInt (0, "socks_type"), + {0}, + WIDGET_CHILD), + WidgetRadio (N_("SOCKS v5"), + WidgetInt (0, "socks_type"), + {1}, + WIDGET_CHILD) +}; + +static const PreferencesWidget chardet_elements[] = { + WidgetCombo (N_("Auto character encoding detector for:"), + WidgetString (0, "chardet_detector"), + {{chardet_detector_presets}}), + WidgetEntry (N_("Fallback character encodings:"), + WidgetString (0, "chardet_fallback")) +}; + +static void send_title_change (); +static void * create_titlestring_table (); + +static const PreferencesWidget playlist_page_widgets[] = { + WidgetLabel (N_("<b>Behavior</b>")), + WidgetCheck (N_("Resume playback on startup"), + WidgetBool (0, "resume_playback_on_startup")), + WidgetCheck (N_("Pause instead of resuming immediately"), + WidgetBool (0, "always_resume_paused"), + WIDGET_CHILD), + WidgetCheck (N_("Advance when the current song is deleted"), + WidgetBool (0, "advance_on_delete")), + WidgetCheck (N_("Clear the playlist when opening files"), + WidgetBool (0, "clear_playlist")), + WidgetCheck (N_("Open files in a temporary playlist"), + WidgetBool (0, "open_to_temporary")), + WidgetLabel (N_("<b>Song Display</b>")), + WidgetCheck (N_("Show song numbers"), + WidgetBool (0, "show_numbers_in_pl", send_title_change)), + WidgetCheck (N_("Show leading zeroes (02:00 vs. 2:00)"), + WidgetBool (0, "leading_zero", send_title_change)), + WidgetCheck (N_("Show hours separately (1:30:00 vs. 90:00)"), + WidgetBool (0, "show_hours", send_title_change)), + WidgetCustomGTK (create_titlestring_table), + WidgetLabel (N_("<b>Export</b>")), + WidgetCheck (N_("Use relative paths when possible"), + WidgetBool (0, "export_relative_paths")) +}; + +static const PreferencesWidget song_info_page_widgets[] = { + WidgetLabel (N_("<b>Album Art</b>")), + WidgetLabel (N_("Search for images matching these words (comma-separated):")), + WidgetEntry (0, WidgetString (0, "cover_name_include")), + WidgetLabel (N_("Exclude images matching these words (comma-separated):")), + WidgetEntry (0, WidgetString (0, "cover_name_exclude")), + WidgetCheck (N_("Search for images matching song file name"), + WidgetBool (0, "use_file_cover")), + WidgetCheck (N_("Search recursively"), + WidgetBool (0, "recurse_for_cover")), + WidgetSpin (N_("Search depth:"), + WidgetInt (0, "recurse_for_cover_depth"), + {0, 100, 1}, + WIDGET_CHILD), + WidgetLabel (N_("<b>Popup Information</b>")), + WidgetCheck (N_("Show popup information"), + WidgetBool (0, "show_filepopup_for_tuple")), + WidgetSpin (N_("Popup delay (tenths of a second):"), + WidgetInt (0, "filepopup_delay"), + {0, 100, 1}, + WIDGET_CHILD), + WidgetCheck (N_("Show time scale for current song"), + WidgetBool (0, "filepopup_showprogressbar"), + WIDGET_CHILD) +}; + +static const PreferencesWidget advanced_page_widgets[] = { + WidgetLabel (N_("<b>Compatibility</b>")), + WidgetCheck (N_("Interpret \\ (backward slash) as a folder delimiter"), + WidgetBool (0, "convert_backslash")), + WidgetTable ({{chardet_elements}}), + WidgetLabel (N_("<b>Playlist</b>")), + WidgetCheck (N_("Add folders recursively"), + WidgetBool (0, "recurse_folders")), + WidgetCheck (N_("Add folders nested within playlist files"), + WidgetBool (0, "folders_in_playlist")), + WidgetLabel (N_("<b>Metadata</b>")), + WidgetCheck (N_("Guess missing metadata from file path"), + WidgetBool (0, "metadata_fallbacks")), + WidgetCheck (N_("Do not load metadata for songs until played"), + WidgetBool (0, "metadata_on_play")), + WidgetCheck (N_("Probe content of files with no recognized file name extension"), + WidgetBool (0, "slow_probe")), + WidgetLabel (N_("<b>Miscellaneous</b>")), + WidgetSpin (N_("Step forward/backward by:"), + WidgetInt (0, "step_size"), + {1, 60, 1, N_("seconds")}), + WidgetSpin (N_("Adjust volume by:"), + WidgetInt (0, "volume_delta"), + {1, 25, 1, N_("percent")}) +}; + +#define TITLESTRING_NPRESETS 8 + +static const char * const titlestring_presets[TITLESTRING_NPRESETS] = { + "${title}", + "${title}${?artist: - ${artist}}", + "${title}${?artist: - ${artist}}${?album: - ${album}}", + "${?artist:${artist} - }${title}", + "${?artist:${artist} - }${?album:${album} - }${title}", + "${?artist:${artist} - }${?album:${album} - }${?track-number:${track-number}. }${title}", + "${?artist:${artist} }${?album:[ ${album} ] }${?artist:- }${?track-number:${track-number}. }${title}", + "${?album:${album} - }${title}" +}; + +static const char * const titlestring_preset_names[TITLESTRING_NPRESETS] = { + N_("TITLE"), + N_("TITLE - ARTIST"), + N_("TITLE - ARTIST - ALBUM"), + N_("ARTIST - TITLE"), + N_("ARTIST - ALBUM - TITLE"), + N_("ARTIST - ALBUM - TRACK. TITLE"), + N_("ARTIST [ ALBUM ] - TRACK. TITLE"), + N_("ALBUM - TITLE") +}; + +static Index<ComboItem> fill_plugin_combo (PluginType type) +{ + Index<ComboItem> elems; + int i = 0; + + for (PluginHandle * plugin : aud_plugin_list (type)) + elems.append (aud_plugin_get_name (plugin), i ++); + + return elems; +} + +static void change_category (int category) +{ + if (aud_get_headless_mode () && category > CATEGORY_APPEARANCE) + category --; + + GtkTreeSelection * selection = gtk_tree_view_get_selection ((GtkTreeView *) category_treeview); + GtkTreePath * path = gtk_tree_path_new_from_indices (category, -1); + gtk_tree_selection_select_path (selection, path); + gtk_tree_path_free (path); +} + +static void category_changed (GtkTreeSelection * selection) +{ + GtkTreeModel * model; + GtkTreeIter iter; + + if (gtk_tree_selection_get_selected (selection, & model, & iter)) + { + GtkTreePath * path = gtk_tree_model_get_path (model, & iter); + int category = gtk_tree_path_get_indices (path)[0]; + gtk_notebook_set_current_page ((GtkNotebook *) category_notebook, category); + gtk_tree_path_free (path); + } +} + +static void send_title_change () +{ + if (aud_drct_get_ready ()) + hook_call ("title change", nullptr); +} + +static void titlestring_tag_menu_cb (GtkMenuItem * menuitem, void * data) +{ + const char * separator = " - "; + auto tag = (const TitleFieldTag *) data; + int pos = gtk_editable_get_position ((GtkEditable *) titlestring_entry); + + /* insert separator as needed */ + if (gtk_entry_get_text ((GtkEntry *) titlestring_entry)[0]) + gtk_editable_insert_text ((GtkEditable *) titlestring_entry, separator, -1, & pos); + + gtk_editable_insert_text ((GtkEditable *) titlestring_entry, _(tag->tag), -1, & pos); + gtk_editable_set_position ((GtkEditable *) titlestring_entry, pos); +} + +static void on_titlestring_help_button_clicked (GtkButton * button, void * menu) +{ + gtk_menu_popup ((GtkMenu *) menu, nullptr, nullptr, nullptr, nullptr, 0, GDK_CURRENT_TIME); +} + +static void update_titlestring_cbox (GtkComboBox * cbox, const char * format) +{ + int preset; + for (preset = 0; preset < TITLESTRING_NPRESETS; preset ++) + { + if (! strcmp (titlestring_presets[preset], format)) + break; + } + + if (gtk_combo_box_get_active (cbox) != preset) + gtk_combo_box_set_active (cbox, preset); +} + +static void on_titlestring_entry_changed (GtkEntry * entry, GtkComboBox * cbox) +{ + const char * format = gtk_entry_get_text (entry); + aud_set_str ("generic_title_format", format); + update_titlestring_cbox (cbox, format); +} + +static void on_titlestring_cbox_changed (GtkComboBox * cbox, GtkEntry * entry) +{ + int preset = gtk_combo_box_get_active (cbox); + if (preset < TITLESTRING_NPRESETS) + gtk_entry_set_text (entry, titlestring_presets[preset]); +} + +static void fill_category_list (GtkTreeView * treeview, GtkNotebook * notebook) +{ + GtkTreeViewColumn * column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, _("Category")); + gtk_tree_view_append_column (treeview, column); + gtk_tree_view_column_set_spacing (column, 2); + + GtkCellRenderer * renderer = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_column_pack_start (column, renderer, false); + gtk_tree_view_column_set_attributes (column, renderer, "pixbuf", 0, nullptr); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, renderer, false); + gtk_tree_view_column_set_attributes (column, renderer, "text", 1, nullptr); + + GtkListStore * store = gtk_list_store_new (CATEGORY_VIEW_N_COLS, + GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT); + gtk_tree_view_set_model (treeview, (GtkTreeModel *) store); + + GtkIconTheme * icon_theme = gtk_icon_theme_get_default (); + int icon_size = audgui_to_native_dpi (48); + + for (const Category & category : categories) + { + if (& category == & categories[CATEGORY_APPEARANCE] && aud_get_headless_mode ()) + continue; + + GtkTreeIter iter; + gtk_list_store_append (store, & iter); + gtk_list_store_set (store, & iter, CATEGORY_VIEW_COL_NAME, + gettext (category.name), -1); + + AudguiPixbuf img (gtk_icon_theme_load_icon (icon_theme, + category.icon, icon_size, (GtkIconLookupFlags) 0, nullptr)); + + if (img) + gtk_list_store_set (store, & iter, CATEGORY_VIEW_COL_ICON, img.get (), -1); + } + + g_object_unref (store); + + GtkTreeSelection * selection = gtk_tree_view_get_selection (treeview); + g_signal_connect (selection, "changed", (GCallback) category_changed, nullptr); +} + +static GtkWidget * create_titlestring_tag_menu () +{ + GtkWidget * titlestring_tag_menu = gtk_menu_new (); + + for (const TitleFieldTag & tag : title_field_tags) + { + GtkWidget * menu_item = gtk_menu_item_new_with_label (_(tag.name)); + gtk_menu_shell_append ((GtkMenuShell *) titlestring_tag_menu, menu_item); + g_signal_connect (menu_item, "activate", + (GCallback) titlestring_tag_menu_cb, (void *) & tag); + } + + gtk_widget_show_all (titlestring_tag_menu); + + return titlestring_tag_menu; +} + +static void create_titlestring_widgets (GtkWidget * * cbox, GtkWidget * * entry) +{ + * cbox = gtk_combo_box_text_new (); + for (int i = 0; i < TITLESTRING_NPRESETS; i ++) + gtk_combo_box_text_append_text ((GtkComboBoxText *) * cbox, _(titlestring_preset_names[i])); + gtk_combo_box_text_append_text ((GtkComboBoxText *) * cbox, _("Custom")); + + * entry = gtk_entry_new (); + + String format = aud_get_str ("generic_title_format"); + update_titlestring_cbox ((GtkComboBox *) * cbox, format); + gtk_entry_set_text ((GtkEntry *) * entry, format); + + g_signal_connect (* cbox, "changed", (GCallback) on_titlestring_cbox_changed, * entry); + g_signal_connect (* entry, "changed", (GCallback) on_titlestring_entry_changed, * cbox); +} + +static void * create_titlestring_table () +{ + GtkWidget * grid = gtk_table_new (0, 0, false); + gtk_table_set_row_spacings ((GtkTable *) grid, 6); + gtk_table_set_col_spacings ((GtkTable *) grid, 6); + + GtkWidget * label = gtk_label_new (_("Title format:")); + gtk_misc_set_alignment ((GtkMisc *) label, 1, 0.5); + gtk_table_attach ((GtkTable *) grid, label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); + + label = gtk_label_new (_("Custom string:")); + gtk_misc_set_alignment ((GtkMisc *) label, 1, 0.5); + gtk_table_attach ((GtkTable *) grid, label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); + + GtkWidget * titlestring_cbox; + create_titlestring_widgets (& titlestring_cbox, & titlestring_entry); + gtk_table_attach_defaults ((GtkTable *) grid, titlestring_cbox, 1, 2, 0, 1); + gtk_table_attach_defaults ((GtkTable *) grid, titlestring_entry, 1, 2, 1, 2); + + GtkWidget * titlestring_help_button = gtk_button_new (); + gtk_widget_set_can_focus (titlestring_help_button, false); + gtk_button_set_focus_on_click ((GtkButton *) titlestring_help_button, false); + gtk_button_set_relief ((GtkButton *) titlestring_help_button, GTK_RELIEF_HALF); + gtk_table_attach ((GtkTable *) grid, titlestring_help_button, 2, 3, 1, 2, + GTK_FILL, GTK_FILL, 0, 0); + + GtkWidget * titlestring_tag_menu = create_titlestring_tag_menu (); + + g_signal_connect (titlestring_help_button, "clicked", + (GCallback) on_titlestring_help_button_clicked, titlestring_tag_menu); + + GtkWidget * image = gtk_image_new_from_icon_name ("list-add", GTK_ICON_SIZE_MENU); + gtk_container_add ((GtkContainer *) titlestring_help_button, image); + + return grid; +} + +static void create_playlist_category () +{ + GtkWidget * vbox = gtk_vbox_new (false, 0); + gtk_container_add ((GtkContainer *) category_notebook, vbox); + audgui_create_widgets (vbox, playlist_page_widgets); +} + +static void create_song_info_category () +{ + GtkWidget * vbox = gtk_vbox_new (false, 0); + gtk_container_add ((GtkContainer *) category_notebook, vbox); + audgui_create_widgets (vbox, song_info_page_widgets); +} + +static void iface_fill_prefs_box () +{ + Plugin * header = (Plugin *) aud_plugin_get_header (aud_plugin_get_current (PluginType::Iface)); + if (header && header->info.prefs) + audgui_create_widgets_with_domain (iface_prefs_box, + header->info.prefs->widgets, header->info.domain); +} + +static void iface_combo_changed () +{ + /* prevent audgui from being shut down during the switch */ + audgui_init (); + + gtk_container_foreach ((GtkContainer *) iface_prefs_box, + (GtkCallback) gtk_widget_destroy, nullptr); + + aud_plugin_enable (aud_plugin_list (PluginType::Iface)[iface_combo_selected], true); + + iface_fill_prefs_box (); + gtk_widget_show_all (iface_prefs_box); + + audgui_cleanup (); +} + +static ArrayRef<ComboItem> iface_combo_fill () +{ + if (! iface_combo_elements.len ()) + { + iface_combo_elements = fill_plugin_combo (PluginType::Iface); + iface_combo_selected = aud_plugin_list (PluginType::Iface). + find (aud_plugin_get_current (PluginType::Iface)); + } + + return {iface_combo_elements.begin (), iface_combo_elements.len ()}; +} + +static void * iface_create_prefs_box () +{ + iface_prefs_box = gtk_vbox_new (false, 0); + iface_fill_prefs_box (); + return iface_prefs_box; +} + +static void create_appearance_category () +{ + GtkWidget * vbox = gtk_vbox_new (false, 0); + gtk_container_add ((GtkContainer *) category_notebook, vbox); + audgui_create_widgets (vbox, appearance_page_widgets); +} + +static void output_combo_changed () +{ + auto & list = aud_plugin_list (PluginType::Output); + PluginHandle * plugin = list[output_combo_selected]; + + if (aud_plugin_enable (plugin, true)) + { + gtk_widget_set_sensitive (output_config_button, aud_plugin_has_configure (plugin)); + gtk_widget_set_sensitive (output_about_button, aud_plugin_has_about (plugin)); + } + else + { + /* set combo box back to current output */ + output_combo_selected = list.find (aud_plugin_get_current (PluginType::Output)); + hook_call ("audgui update output combo", nullptr); + } +} + +static ArrayRef<ComboItem> output_combo_fill () +{ + if (! output_combo_elements.len ()) + { + output_combo_elements = fill_plugin_combo (PluginType::Output); + output_combo_selected = aud_plugin_list (PluginType::Output) + .find (aud_plugin_get_current (PluginType::Output)); + } + + return {output_combo_elements.begin (), output_combo_elements.len ()}; +} + +static void output_bit_depth_changed () +{ + aud_output_reset (OutputReset::ReopenStream); +} + +static void * output_create_config_button () +{ + auto do_config = [] (void *) + { audgui_show_plugin_prefs (aud_plugin_get_current (PluginType::Output)); }; + + bool enabled = aud_plugin_has_configure (aud_plugin_get_current (PluginType::Output)); + + output_config_button = audgui_button_new (_("_Settings"), + "preferences-system", do_config, nullptr); + gtk_widget_set_sensitive (output_config_button, enabled); + + return output_config_button; +} + +static void * output_create_about_button () +{ + auto do_about = [] (void *) + { audgui_show_plugin_about (aud_plugin_get_current (PluginType::Output)); }; + + bool enabled = aud_plugin_has_about (aud_plugin_get_current (PluginType::Output)); + + output_about_button = audgui_button_new (_("_About"), "help-about", do_about, nullptr); + gtk_widget_set_sensitive (output_about_button, enabled); + + return output_about_button; +} + +static void record_toggled (GtkToggleButton * button) +{ + aud_drct_enable_record (gtk_toggle_button_get_active (button)); +} + +static void * record_create_checkbox () +{ + record_checkbox = gtk_check_button_new (); + g_signal_connect (record_checkbox, "toggled", (GCallback) record_toggled, nullptr); + return record_checkbox; +} + +static void * record_create_config_button () +{ + auto do_config = [] (void *) + { + if (aud_drct_get_record_enabled ()) + audgui_show_plugin_prefs (aud_drct_get_record_plugin ()); + }; + + return (record_config_button = audgui_button_new (_("_Settings"), + "preferences-system", do_config, nullptr)); +} + +static void * record_create_about_button () +{ + auto do_about = [] (void *) + { + if (aud_drct_get_record_enabled ()) + audgui_show_plugin_about (aud_drct_get_record_plugin ()); + }; + + return (record_about_button = audgui_button_new (_("_About"), "help-about", + do_about, nullptr)); +} + +static void record_update (void * = nullptr, void * = nullptr) +{ + auto p = aud_drct_get_record_plugin (); + + if (p) + { + bool enabled = aud_drct_get_record_enabled (); + + gtk_widget_set_sensitive (record_checkbox, true); + gtk_button_set_label ((GtkButton *) record_checkbox, + str_printf (_("Enable audio stream recording with %s"), aud_plugin_get_name (p))); + gtk_toggle_button_set_active ((GtkToggleButton *) record_checkbox, enabled); + gtk_widget_set_sensitive (record_config_button, enabled && aud_plugin_has_configure (p)); + gtk_widget_set_sensitive (record_about_button, enabled && aud_plugin_has_about (p)); + } + else + { + gtk_widget_set_sensitive (record_checkbox, false); + gtk_button_set_label ((GtkButton *) record_checkbox, + _("No audio recording plugin available")); + gtk_toggle_button_set_active ((GtkToggleButton *) record_checkbox, false); + gtk_widget_set_sensitive (record_config_button, false); + gtk_widget_set_sensitive (record_about_button, false); + } +} + +static void create_audio_category () +{ + GtkWidget * audio_page_vbox = gtk_vbox_new (false, 0); + audgui_create_widgets (audio_page_vbox, audio_page_widgets); + gtk_container_add ((GtkContainer *) category_notebook, audio_page_vbox); +} + +static void create_connectivity_category () +{ + GtkWidget * connectivity_page_vbox = gtk_vbox_new (false, 0); + gtk_container_add ((GtkContainer *) category_notebook, connectivity_page_vbox); + + GtkWidget * vbox = gtk_vbox_new (false, 0); + gtk_box_pack_start ((GtkBox *) connectivity_page_vbox, vbox, true, true, 0); + + audgui_create_widgets (vbox, connectivity_page_widgets); +} + +static void create_plugin_category () +{ + plugin_notebook = gtk_notebook_new (); + gtk_container_add ((GtkContainer *) category_notebook, plugin_notebook); + + for (const PluginCategory & category : plugin_categories) + gtk_notebook_append_page ((GtkNotebook *) plugin_notebook, + plugin_view_new (category.type), gtk_label_new (_(category.name))); +} + +static void create_advanced_category () +{ + GtkWidget * advanced_page_vbox = gtk_vbox_new (false, 0); + audgui_create_widgets (advanced_page_vbox, advanced_page_widgets); + gtk_container_add ((GtkContainer *) category_notebook, advanced_page_vbox); +} + +static void destroy_cb () +{ + hook_dissociate ("enable record", record_update); + + prefswin = nullptr; + category_treeview = nullptr; + category_notebook = nullptr; + titlestring_entry = nullptr; + + iface_combo_elements.clear (); + output_combo_elements.clear (); +} + +static void create_prefs_window () +{ + prefswin = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_type_hint ((GtkWindow *) prefswin, GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_container_set_border_width ((GtkContainer *) prefswin, 12); + gtk_window_set_title ((GtkWindow *) prefswin, _("Audacious Settings")); + + GtkWidget * vbox = gtk_vbox_new (false, 0); + gtk_container_add ((GtkContainer *) prefswin, vbox); + + GtkWidget * hbox = gtk_hbox_new (false, 6); + gtk_box_pack_start ((GtkBox *) vbox, hbox, true, true, 0); + + GtkWidget * scrolledwindow = gtk_scrolled_window_new (nullptr, nullptr); + gtk_box_pack_start ((GtkBox *) hbox, scrolledwindow, false, false, 0); + gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolledwindow, + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolledwindow, GTK_SHADOW_IN); + + category_treeview = gtk_tree_view_new (); + gtk_container_add ((GtkContainer *) scrolledwindow, category_treeview); + gtk_widget_set_size_request (scrolledwindow, audgui_get_dpi () * 7 / 4, -1); + gtk_tree_view_set_headers_visible ((GtkTreeView *) category_treeview, false); + + category_notebook = gtk_notebook_new (); + gtk_box_pack_start ((GtkBox *) hbox, category_notebook, true, true, 0); + + gtk_widget_set_can_focus (category_notebook, false); + gtk_notebook_set_show_tabs ((GtkNotebook *) category_notebook, false); + gtk_notebook_set_show_border ((GtkNotebook *) category_notebook, false); + + if (! aud_get_headless_mode ()) + create_appearance_category (); + + create_audio_category (); + create_connectivity_category (); + create_playlist_category (); + create_song_info_category (); + create_plugin_category (); + create_advanced_category (); + + GtkWidget * hseparator = gtk_hseparator_new (); + gtk_box_pack_start ((GtkBox *) vbox, hseparator, false, false, 6); + + hbox = gtk_hbox_new (false, 0); + gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 0); + + GtkWidget * audversionlabel = gtk_label_new (aud_version_string); + gtk_box_pack_start ((GtkBox *) hbox, audversionlabel, false, false, 0); + gtk_label_set_use_markup ((GtkLabel *) audversionlabel, true); + + GtkWidget * prefswin_button_box = gtk_hbutton_box_new (); + gtk_box_pack_start ((GtkBox *) hbox, prefswin_button_box, true, true, 0); + gtk_button_box_set_layout ((GtkButtonBox *) prefswin_button_box, GTK_BUTTONBOX_END); + gtk_box_set_spacing ((GtkBox *) prefswin_button_box, 6); + + GtkWidget * close = audgui_button_new (_("_Close"), "window-close", + (AudguiCallback) gtk_widget_destroy, prefswin); + gtk_container_add ((GtkContainer *) prefswin_button_box, close); + gtk_widget_set_can_default (close, true); + + fill_category_list ((GtkTreeView *) category_treeview, (GtkNotebook *) category_notebook); + + record_update (); + hook_associate ("enable record", record_update, nullptr); + + gtk_widget_show_all (vbox); + + g_signal_connect (prefswin, "destroy", (GCallback) destroy_cb, nullptr); + + audgui_destroy_on_escape (prefswin); +} + +EXPORT void audgui_show_prefs_window () +{ + if (! prefswin) + create_prefs_window (); + + change_category (CATEGORY_APPEARANCE); + + gtk_window_present ((GtkWindow *) prefswin); +} + +EXPORT void audgui_show_prefs_for_plugin_type (PluginType type) +{ + if (! prefswin) + create_prefs_window (); + + if (type == PluginType::Iface) + change_category (CATEGORY_APPEARANCE); + else if (type == PluginType::Output) + change_category (CATEGORY_AUDIO); + else + { + change_category (CATEGORY_PLUGINS); + + for (const PluginCategory & category : plugin_categories) + { + if (category.type == type) + gtk_notebook_set_current_page ((GtkNotebook *) plugin_notebook, + & category - plugin_categories); + } + } + + gtk_window_present ((GtkWindow *) prefswin); +} + +EXPORT void audgui_hide_prefs_window () +{ + if (prefswin) + gtk_widget_destroy (prefswin); +} diff --git a/src/libaudgui/preset-browser.cc b/src/libaudgui/preset-browser.cc new file mode 100644 index 0000000..c67b3f2 --- /dev/null +++ b/src/libaudgui/preset-browser.cc @@ -0,0 +1,132 @@ +/* + * preset-browser.c + * Copyright 2014-2015 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#define AUD_GLIB_INTEGRATION +#include "internal.h" +#include "libaudgui.h" +#include "preset-browser.h" + +#include <gtk/gtk.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/drct.h> +#include <libaudcore/i18n.h> +#include <libaudcore/vfs.h> + +typedef void (* PresetAction) (const char * filename, const EqualizerPreset * preset); + +static void browser_response (GtkWidget * dialog, int response, void * data) +{ + if (response == GTK_RESPONSE_ACCEPT) + { + CharPtr filename (gtk_file_chooser_get_uri ((GtkFileChooser *) dialog)); + auto preset = (const EqualizerPreset *) + g_object_get_data ((GObject *) dialog, "eq-preset"); + + ((PresetAction) data) (filename, preset); + } + + gtk_widget_destroy (dialog); +} + +static void show_preset_browser (const char * title, gboolean save, + const char * default_filename, PresetAction callback, + const EqualizerPreset * preset) +{ + GtkWidget * browser = gtk_file_chooser_dialog_new (title, nullptr, save ? + GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN, _("Cancel"), + GTK_RESPONSE_CANCEL, save ? _("Save") : _("Load"), GTK_RESPONSE_ACCEPT, + nullptr); + + gtk_file_chooser_set_local_only ((GtkFileChooser *) browser, false); + + if (default_filename) + gtk_file_chooser_set_current_name ((GtkFileChooser *) browser, default_filename); + + if (preset) + g_object_set_data_full ((GObject *) browser, "eq-preset", + new EqualizerPreset (* preset), aud::delete_obj<EqualizerPreset>); + + g_signal_connect (browser, "response", (GCallback) browser_response, (void *) callback); + + audgui_show_unique_window (AUDGUI_PRESET_BROWSER_WINDOW, browser); +} + +static void do_load_file (const char * filename, const EqualizerPreset *) +{ + Index<EqualizerPreset> presets; + presets.append (); + + VFSFile file (filename, "r"); + if (! file || ! aud_load_preset_file (presets[0], file)) + return; + + audgui_import_eq_presets (presets); +} + +void eq_preset_load_file () +{ + show_preset_browser (_("Load Preset File"), false, nullptr, do_load_file, nullptr); +} + +static void do_load_eqf (const char * filename, const EqualizerPreset *) +{ + VFSFile file (filename, "r"); + if (! file) + return; + + audgui_import_eq_presets (aud_import_winamp_presets (file)); +} + +void eq_preset_load_eqf () +{ + show_preset_browser (_("Load EQF File"), false, nullptr, do_load_eqf, nullptr); +} + +static void do_save_file (const char * filename, const EqualizerPreset * preset) +{ + g_return_if_fail (preset); + + VFSFile file (filename, "w"); + if (file) + aud_save_preset_file (* preset, file); +} + +void eq_preset_save_file (const EqualizerPreset & preset) +{ + StringBuf name = str_concat ({preset.name, ".preset"}); + show_preset_browser (_("Save Preset File"), true, name, do_save_file, & preset); +} + +static void do_save_eqf (const char * filename, const EqualizerPreset * preset) +{ + g_return_if_fail (preset); + + VFSFile file (filename, "w"); + if (! file) + return; + + aud_export_winamp_preset (* preset, file); +} + +void eq_preset_save_eqf (const EqualizerPreset & preset) +{ + StringBuf name = str_concat ({preset.name, ".eqf"}); + show_preset_browser (_("Save EQF File"), true, name, do_save_eqf, & preset); +} diff --git a/src/libaudgui/preset-browser.h b/src/libaudgui/preset-browser.h new file mode 100644 index 0000000..3d6a9ce --- /dev/null +++ b/src/libaudgui/preset-browser.h @@ -0,0 +1,30 @@ +/* + * preset-browser.h + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef AUDGUI_PRESET_BROWSER_H +#define AUDGUI_PRESET_BROWSER_H + +#include <libaudcore/equalizer.h> + +void eq_preset_load_file (); +void eq_preset_load_eqf (); +void eq_preset_save_file (const EqualizerPreset & preset); +void eq_preset_save_eqf (const EqualizerPreset & preset); + +#endif // AUDGUI_PRESET_BROWSER_H diff --git a/src/libaudgui/queue-manager.cc b/src/libaudgui/queue-manager.cc new file mode 100644 index 0000000..67a6ef6 --- /dev/null +++ b/src/libaudgui/queue-manager.cc @@ -0,0 +1,213 @@ +/* + * queue-manager.c + * Copyright 2011-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> + +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/playlist.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" +#include "list.h" + +enum { + COLUMN_ENTRY, + COLUMN_TITLE +}; + +static void get_value (void * user, int row, int column, GValue * value) +{ + auto list = Playlist::active_playlist (); + int entry = list.queue_get_entry (row); + + switch (column) + { + case COLUMN_ENTRY: + g_value_set_int (value, 1 + entry); + break; + case COLUMN_TITLE: + Tuple tuple = list.entry_tuple (entry, Playlist::NoWait); + g_value_set_string (value, tuple.get_str (Tuple::FormattedTitle)); + break; + } +} + +static bool get_selected (void * user, int row) +{ + auto list = Playlist::active_playlist (); + return list.entry_selected (list.queue_get_entry (row)); +} + +static void set_selected (void * user, int row, bool selected) +{ + auto list = Playlist::active_playlist (); + list.select_entry (list.queue_get_entry (row), selected); +} + +static void select_all (void * user, bool selected) +{ + auto list = Playlist::active_playlist (); + int count = list.n_queued (); + + for (int i = 0; i < count; i ++) + list.select_entry (list.queue_get_entry (i), selected); +} + +static void shift_rows (void * user, int row, int before) +{ + Index<int> shift; + auto list = Playlist::active_playlist (); + int count = list.n_queued (); + + for (int i = 0; i < count; i ++) + { + int entry = list.queue_get_entry (i); + + if (list.entry_selected (entry)) + { + shift.append (entry); + + if (i < before) + before --; + } + } + + list.queue_remove_selected (); + + for (int i = 0; i < shift.len (); i ++) + list.queue_insert (before + i, shift[i]); +} + +static const AudguiListCallbacks callbacks = { + get_value, + get_selected, + set_selected, + select_all, + 0, // activate_row + 0, // right_click + shift_rows +}; + +static void remove_selected (void *) +{ + auto list = Playlist::active_playlist (); + int count = list.n_queued (); + + for (int i = 0; i < count; ) + { + int entry = list.queue_get_entry (i); + + if (list.entry_selected (entry)) + { + list.queue_remove (i); + list.select_entry (entry, false); + count --; + } + else + i ++; + } +} + +static void update_hook (void * data, void * user) +{ + GtkWidget * qm_list = (GtkWidget *) user; + + int oldrows = audgui_list_row_count (qm_list); + int newrows = Playlist::active_playlist ().n_queued (); + int focus = audgui_list_get_focus (qm_list); + + audgui_list_update_rows (qm_list, 0, aud::min (oldrows, newrows)); + audgui_list_update_selection (qm_list, 0, aud::min (oldrows, newrows)); + + if (newrows > oldrows) + audgui_list_insert_rows (qm_list, oldrows, newrows - oldrows); + if (newrows < oldrows) + audgui_list_delete_rows (qm_list, newrows, oldrows - newrows); + + if (focus > newrows - 1) + audgui_list_set_focus (qm_list, newrows - 1); +} + +static void destroy_cb () +{ + hook_dissociate ("playlist activate", update_hook); + hook_dissociate ("playlist update", update_hook); +} + +static gboolean keypress_cb (GtkWidget * widget, GdkEventKey * event) +{ + if (event->keyval == GDK_KEY_A && (event->state & GDK_CONTROL_MASK)) + select_all (nullptr, true); + else if (event->keyval == GDK_KEY_Delete) + remove_selected (nullptr); + else if (event->keyval == GDK_KEY_Escape) + gtk_widget_destroy (widget); + else + return false; + + return true; +} + +static GtkWidget * create_queue_manager () +{ + int dpi = audgui_get_dpi (); + + GtkWidget * qm_win = gtk_dialog_new (); + gtk_window_set_title ((GtkWindow *) qm_win, _("Queue Manager")); + gtk_window_set_default_size ((GtkWindow *) qm_win, 3 * dpi, 2 * dpi); + + GtkWidget * vbox = gtk_dialog_get_content_area ((GtkDialog *) qm_win); + + GtkWidget * scrolled = gtk_scrolled_window_new (nullptr, nullptr); + gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) scrolled, GTK_SHADOW_IN); + gtk_scrolled_window_set_policy ((GtkScrolledWindow *) scrolled, + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_box_pack_start ((GtkBox *) vbox, scrolled, true, true, 0); + + int count = Playlist::active_playlist ().n_queued (); + GtkWidget * qm_list = audgui_list_new (& callbacks, nullptr, count); + gtk_tree_view_set_headers_visible ((GtkTreeView *) qm_list, false); + audgui_list_add_column (qm_list, nullptr, 0, G_TYPE_INT, 7); + audgui_list_add_column (qm_list, nullptr, 1, G_TYPE_STRING, -1); + gtk_container_add ((GtkContainer *) scrolled, qm_list); + + GtkWidget * button1 = audgui_button_new (_("_Unqueue"), "list-remove", remove_selected, nullptr); + GtkWidget * button2 = audgui_button_new (_("_Close"), "window-close", + (AudguiCallback) gtk_widget_destroy, qm_win); + + gtk_dialog_add_action_widget ((GtkDialog *) qm_win, button1, GTK_RESPONSE_NONE); + gtk_dialog_add_action_widget ((GtkDialog *) qm_win, button2, GTK_RESPONSE_NONE); + + hook_associate ("playlist activate", update_hook, qm_list); + hook_associate ("playlist update", update_hook, qm_list); + + g_signal_connect (qm_win, "destroy", (GCallback) destroy_cb, nullptr); + g_signal_connect (qm_win, "key-press-event", (GCallback) keypress_cb, nullptr); + + return qm_win; +} + +EXPORT void audgui_queue_manager_show () +{ + if (! audgui_reshow_unique_window (AUDGUI_QUEUE_MANAGER_WINDOW)) + audgui_show_unique_window (AUDGUI_QUEUE_MANAGER_WINDOW, create_queue_manager ()); +} diff --git a/src/libaudgui/scaled-image.cc b/src/libaudgui/scaled-image.cc new file mode 100644 index 0000000..cc079c9 --- /dev/null +++ b/src/libaudgui/scaled-image.cc @@ -0,0 +1,101 @@ +/* + * scaled-image.c + * Copyright 2012-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <libaudgui/libaudgui-gtk.h> + +static GdkPixbuf * get_scaled (GtkWidget * widget, int maxwidth, int maxheight) +{ + GdkPixbuf * unscaled = (GdkPixbuf *) g_object_get_data ((GObject *) widget, "pixbuf-unscaled"); + + if (! unscaled) + return nullptr; + + int width = gdk_pixbuf_get_width (unscaled); + int height = gdk_pixbuf_get_height (unscaled); + + if (width > maxwidth || height > maxheight) + { + if (width * maxheight > height * maxwidth) + { + height = aud::rescale (height, width, maxwidth); + width = maxwidth; + } + else + { + width = aud::rescale (width, height, maxheight); + height = maxheight; + } + } + + GdkPixbuf * scaled = (GdkPixbuf *) g_object_get_data ((GObject *) widget, "pixbuf-scaled"); + + if (scaled) + { + if (gdk_pixbuf_get_width (scaled) == width && gdk_pixbuf_get_height (scaled) == height) + return scaled; + } + + scaled = gdk_pixbuf_scale_simple (unscaled, width, height, GDK_INTERP_BILINEAR); + g_object_set_data_full ((GObject *) widget, "pixbuf-scaled", scaled, g_object_unref); + + return scaled; +} + +static int expose_cb (GtkWidget * widget, GdkEventExpose * event) +{ + GdkRectangle rect; + gtk_widget_get_allocation (widget, & rect); + + GdkPixbuf * scaled = get_scaled (widget, rect.width, rect.height); + + if (scaled) + { + int x = (rect.width - gdk_pixbuf_get_width (scaled)) / 2; + int y = (rect.height - gdk_pixbuf_get_height (scaled)) / 2; + + cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget)); + gdk_cairo_set_source_pixbuf (cr, scaled, x, y); + cairo_paint (cr); + cairo_destroy (cr); + } + + return true; +} + +EXPORT void audgui_scaled_image_set (GtkWidget * widget, GdkPixbuf * pixbuf) +{ + if (pixbuf) + g_object_ref (pixbuf); + + g_object_set_data_full ((GObject *) widget, "pixbuf-unscaled", pixbuf, g_object_unref); + g_object_set_data_full ((GObject *) widget, "pixbuf-scaled", nullptr, g_object_unref); + + gtk_widget_queue_draw (widget); +} + +EXPORT GtkWidget * audgui_scaled_image_new (GdkPixbuf * pixbuf) +{ + GtkWidget * widget = gtk_drawing_area_new (); + + g_signal_connect (widget, "expose-event", (GCallback) expose_cb, nullptr); + + audgui_scaled_image_set (widget, pixbuf); + + return widget; +} diff --git a/src/libaudgui/status.cc b/src/libaudgui/status.cc new file mode 100644 index 0000000..6ba9b3c --- /dev/null +++ b/src/libaudgui/status.cc @@ -0,0 +1,116 @@ +/* + * status.c + * Copyright 2014 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gtk/gtk.h> + +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> + +#include "internal.h" +#include "libaudgui-gtk.h" + +static GtkWidget * progress_window; +static GtkWidget * progress_label, * progress_label_2; +static GtkWidget * error_window, * info_window; + +static void create_progress_window () +{ + progress_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_type_hint ((GtkWindow *) progress_window, GDK_WINDOW_TYPE_HINT_DIALOG); + gtk_window_set_title ((GtkWindow *) progress_window, _("Working ...")); + gtk_window_set_resizable ((GtkWindow *) progress_window, false); + gtk_container_set_border_width ((GtkContainer *) progress_window, 6); + + GtkWidget * vbox = gtk_vbox_new (false, 6); + gtk_container_add ((GtkContainer *) progress_window, vbox); + + progress_label = gtk_label_new (nullptr); + gtk_label_set_width_chars ((GtkLabel *) progress_label, 40); + gtk_label_set_max_width_chars ((GtkLabel *) progress_label, 40); + gtk_label_set_ellipsize ((GtkLabel *) progress_label, PANGO_ELLIPSIZE_MIDDLE); + gtk_box_pack_start ((GtkBox *) vbox, progress_label, false, false, 0); + + progress_label_2 = gtk_label_new (nullptr); + gtk_label_set_width_chars ((GtkLabel *) progress_label_2, 40); + gtk_label_set_max_width_chars ((GtkLabel *) progress_label_2, 40); + gtk_label_set_ellipsize ((GtkLabel *) progress_label, PANGO_ELLIPSIZE_MIDDLE); + gtk_box_pack_start ((GtkBox *) vbox, progress_label_2, false, false, 0); + + gtk_widget_show_all (progress_window); + + g_signal_connect (progress_window, "destroy", + (GCallback) gtk_widget_destroyed, & progress_window); +} + +static void show_progress (void * data, void * user) +{ + if (! progress_window) + create_progress_window (); + + gtk_label_set_text ((GtkLabel *) progress_label, (const char *) data); +} + +static void show_progress_2 (void * data, void * user) +{ + if (! progress_window) + create_progress_window (); + + gtk_label_set_text ((GtkLabel *) progress_label_2, (const char *) data); +} + +static void hide_progress (void * data, void * user) +{ + if (progress_window) + gtk_widget_destroy (progress_window); +} + +static void show_error (void * data, void * user) +{ + audgui_simple_message (& error_window, GTK_MESSAGE_ERROR, _("Error"), (const char *) data); +} + +static void show_info (void * data, void * user) +{ + audgui_simple_message (& info_window, GTK_MESSAGE_INFO, _("Information"), (const char *) data); +} + +void status_init () +{ + hook_associate ("ui show progress", show_progress, nullptr); + hook_associate ("ui show progress 2", show_progress_2, nullptr); + hook_associate ("ui hide progress", hide_progress, nullptr); + hook_associate ("ui show error", show_error, nullptr); + hook_associate ("ui show info", show_info, nullptr); +} + +void status_cleanup () +{ + hook_dissociate ("ui show progress", show_progress); + hook_dissociate ("ui show progress 2", show_progress_2); + hook_dissociate ("ui hide progress", hide_progress); + hook_dissociate ("ui show error", show_error); + hook_dissociate ("ui show info", show_info); + + if (progress_window) + gtk_widget_destroy (progress_window); + if (error_window) + gtk_widget_destroy (error_window); + if (info_window) + gtk_widget_destroy (info_window); +} diff --git a/src/libaudgui/urilist.cc b/src/libaudgui/urilist.cc new file mode 100644 index 0000000..6874f4f --- /dev/null +++ b/src/libaudgui/urilist.cc @@ -0,0 +1,88 @@ +/* + * urilist.c + * Copyright 2010-2011 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <string.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/drct.h> +#include <libaudcore/playlist.h> + +#include "libaudgui.h" + +static String check_uri (const char * name) +{ + return strstr (name, "://") ? String (name) : String (filename_to_uri (name)); +} + +static Index<PlaylistAddItem> urilist_to_index (const char * list) +{ + Index<PlaylistAddItem> index; + const char * end, * next; + + while (list[0]) + { + if ((end = strchr (list, '\n'))) + { + next = end + 1; + if (end > list && end[-1] == '\r') + end --; + } + else + next = end = strchr (list, 0); + + if (end > list) + index.append (check_uri (str_copy (list, end - list))); + + list = next; + } + + return index; +} + +EXPORT void audgui_urilist_open (const char * list) +{ + aud_drct_pl_open_list (urilist_to_index (list)); +} + +EXPORT void audgui_urilist_insert (Playlist playlist, int at, const char * list) +{ + playlist.insert_items (at, urilist_to_index (list), false); +} + +EXPORT Index<char> audgui_urilist_create_from_selected (Playlist playlist) +{ + playlist.cache_selected (); + + Index<char> buf; + int entries = playlist.n_entries (); + + for (int i = 0; i < entries; i ++) + { + if (playlist.entry_selected (i)) + { + if (buf.len ()) + buf.append ('\n'); + + String filename = playlist.entry_filename (i); + buf.insert (filename, -1, strlen (filename)); + } + } + + return buf; +} diff --git a/src/libaudgui/url-opener.cc b/src/libaudgui/url-opener.cc new file mode 100644 index 0000000..c994b7a --- /dev/null +++ b/src/libaudgui/url-opener.cc @@ -0,0 +1,114 @@ +/* + * url-opener.c + * Copyright 2012-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <gtk/gtk.h> + +#include <libaudcore/drct.h> +#include <libaudcore/i18n.h> +#include <libaudcore/preferences.h> +#include <libaudcore/runtime.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +static void open_cb (void * entry) +{ + const char * text = gtk_entry_get_text ((GtkEntry *) entry); + gboolean open = GPOINTER_TO_INT (g_object_get_data ((GObject *) entry, "open")); + + if (open) + aud_drct_pl_open (text); + else + aud_drct_pl_add (text, -1); + + if (aud_get_bool ("save_url_history")) + aud_history_add (text); +} + +static void clear_cb (void * combo) +{ + /* no gtk_combo_box_text_clear()? */ + gtk_list_store_clear ((GtkListStore *) gtk_combo_box_get_model ((GtkComboBox *) combo)); + aud_history_clear (); +} + +static GtkWidget * create_url_opener (bool open) +{ + static const PreferencesWidget widgets[] = { + WidgetCheck (N_("_Save to history"), + WidgetBool (0, "save_url_history")) + }; + + const char * title, * verb, * icon; + + if (open) + { + title = _("Open URL"); + verb = _("_Open"); + icon = "document-open"; + } + else + { + title = _("Add URL"); + verb = _("_Add"); + icon = "list-add"; + } + + GtkWidget * combo = gtk_combo_box_text_new_with_entry (); + GtkWidget * entry = gtk_bin_get_child ((GtkBin *) combo); + gtk_entry_set_activates_default ((GtkEntry *) entry, true); + + for (int i = 0;; i++) + { + String item = aud_history_get (i); + if (! item) + break; + + gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, item); + } + + g_object_set_data ((GObject *) entry, "open", GINT_TO_POINTER (open)); + + GtkWidget * hbox = gtk_hbox_new (false, 6); + audgui_create_widgets (hbox, widgets); + + GtkWidget * clear_button = audgui_button_new (_("C_lear history"), + "edit-clear", clear_cb, combo); + gtk_box_pack_end ((GtkBox *) hbox, clear_button, false, false, 0); + + GtkWidget * vbox = gtk_vbox_new (false, 6); + gtk_box_pack_start ((GtkBox *) vbox, combo, false, false, 0); + gtk_box_pack_start ((GtkBox *) vbox, hbox, false, false, 0); + + GtkWidget * button1 = audgui_button_new (verb, icon, open_cb, entry); + GtkWidget * button2 = audgui_button_new (_("_Cancel"), "process-stop", nullptr, nullptr); + + GtkWidget * dialog = audgui_dialog_new (GTK_MESSAGE_OTHER, title, + _("Enter URL:"), button1, button2); + gtk_widget_set_size_request (dialog, 4 * audgui_get_dpi (), -1); + audgui_dialog_add_widget (dialog, vbox); + + return dialog; +} + +EXPORT void audgui_show_add_url_window (bool open) +{ + audgui_show_unique_window (AUDGUI_URL_OPENER_WINDOW, create_url_opener (open)); +} diff --git a/src/libaudgui/util.cc b/src/libaudgui/util.cc new file mode 100644 index 0000000..72cd9c5 --- /dev/null +++ b/src/libaudgui/util.cc @@ -0,0 +1,394 @@ +/* + * util.c + * Copyright 2010-2012 John Lindgren and Michał Lipski + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <math.h> +#include <string.h> + +#ifdef _WIN32 +#include <windows.h> +#endif + +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> + +#define AUD_GLIB_INTEGRATION +#include <libaudcore/audstrings.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/runtime.h> + +#include "internal.h" +#include "libaudgui.h" +#include "libaudgui-gtk.h" + +#define PORTABLE_DPI 96 + +EXPORT int audgui_get_dpi () +{ + static int dpi = 0; + + if (! dpi) + { +#ifdef _WIN32 + HDC screen = GetDC (nullptr); + dpi = (GetDeviceCaps (screen, LOGPIXELSX) + GetDeviceCaps (screen, LOGPIXELSY)) / 2; + ReleaseDC (nullptr, screen); +#else + GdkScreen * screen = gdk_screen_get_default (); + + /* force GTK settings to be loaded for the GDK screen */ + (void) gtk_settings_get_for_screen (screen); + + dpi = round (gdk_screen_get_resolution (screen)); +#endif + + dpi = aud::max (PORTABLE_DPI, dpi); + } + + return dpi; +} + +EXPORT int audgui_to_native_dpi (int size) +{ + return aud::rescale (size, PORTABLE_DPI, audgui_get_dpi ()); +} + +EXPORT int audgui_to_portable_dpi (int size) +{ + return aud::rescale (size, audgui_get_dpi (), PORTABLE_DPI); +} + +EXPORT int audgui_get_digit_width (GtkWidget * widget) +{ + int width; + PangoLayout * layout = gtk_widget_create_pango_layout (widget, "0123456789"); + PangoFontDescription * desc = pango_font_description_new (); + pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD); + pango_layout_set_font_description (layout, desc); + pango_layout_get_pixel_size (layout, & width, nullptr); + pango_font_description_free (desc); + g_object_unref (layout); + return (width + 9) / 10; +} + +EXPORT void audgui_get_mouse_coords (GtkWidget * widget, int * x, int * y) +{ + gtk_widget_get_pointer (widget, x, y); +} + +EXPORT void audgui_get_mouse_coords (GdkScreen * screen, int * x, int * y) +{ + gdk_display_get_pointer (gdk_screen_get_display (screen), nullptr, x, y, nullptr); +} + +EXPORT void audgui_get_monitor_geometry (GdkScreen * screen, int x, int y, GdkRectangle * geom) +{ + int monitors = gdk_screen_get_n_monitors (screen); + + for (int i = 0; i < monitors; i ++) + { + gdk_screen_get_monitor_geometry (screen, i, geom); + if (x >= geom->x && x < geom->x + geom->width && y >= geom->y && y < geom->y + geom->height) + return; + } + + /* fall back to entire screen */ + geom->x = 0; + geom->y = 0; + geom->width = gdk_screen_get_width (screen); + geom->height = gdk_screen_get_height (screen); +} + +static gboolean escape_destroy_cb (GtkWidget * widget, GdkEventKey * event) +{ + if (event->keyval == GDK_KEY_Escape) + { + gtk_widget_destroy (widget); + return true; + } + + return false; +} + +EXPORT void audgui_destroy_on_escape (GtkWidget * widget) +{ + g_signal_connect (widget, "key-press-event", (GCallback) escape_destroy_cb, nullptr); +} + +EXPORT GtkWidget * audgui_button_new (const char * text, const char * icon, + AudguiCallback callback, void * data) +{ + GtkWidget * button = gtk_button_new_with_mnemonic (text); + + if (icon) + { + GtkWidget * image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU); + gtk_button_set_image ((GtkButton *) button, image); + } + + if (callback) + g_signal_connect_swapped (button, "clicked", (GCallback) callback, data); + + return button; +} + +struct FileEntryData { + GtkFileChooserAction action; + String title; +}; + +static void entry_response_cb (GtkWidget * dialog, int response, GtkWidget * entry) +{ + if (response == GTK_RESPONSE_ACCEPT) + { + CharPtr uri (gtk_file_chooser_get_uri ((GtkFileChooser *) dialog)); + if (uri) + audgui_file_entry_set_uri (entry, uri); + } + + gtk_widget_destroy (dialog); +} + +static void entry_browse_cb (GtkWidget * entry, GtkEntryIconPosition pos, + GdkEvent * event, const FileEntryData * data) +{ + GtkWidget * dialog = gtk_file_chooser_dialog_new (data->title, nullptr, + data->action, _("Open"), GTK_RESPONSE_ACCEPT, _("Cancel"), + GTK_RESPONSE_REJECT, nullptr); + + gtk_file_chooser_set_local_only ((GtkFileChooser *) dialog, false); + + String uri = audgui_file_entry_get_uri (entry); + if (uri) + gtk_file_chooser_set_uri ((GtkFileChooser *) dialog, uri); + + g_signal_connect (dialog, "response", (GCallback) entry_response_cb, entry); + g_signal_connect_object (entry, "destroy", (GCallback) gtk_widget_destroy, + dialog, G_CONNECT_SWAPPED); + + gtk_widget_show (dialog); +} + +EXPORT GtkWidget * audgui_file_entry_new (GtkFileChooserAction action, const char * title) +{ + GtkWidget * entry = gtk_entry_new (); + + auto data = new FileEntryData {action, String (title)}; + g_object_set_data_full ((GObject *) entry, "file-entry-data", data, + aud::delete_obj<FileEntryData>); + + gtk_entry_set_icon_from_icon_name ((GtkEntry *) entry, + GTK_ENTRY_ICON_SECONDARY, "document-open"); + g_signal_connect (entry, "icon-press", (GCallback) entry_browse_cb, data); + + return entry; +} + +EXPORT String audgui_file_entry_get_uri (GtkWidget * entry) +{ + const char * text = gtk_entry_get_text ((GtkEntry *) entry); + + if (! text[0]) + return String (); + else if (strstr (text, "://")) + return String (text); + else + return String (filename_to_uri (filename_normalize (filename_expand (str_copy (text))))); +} + +EXPORT void audgui_file_entry_set_uri (GtkWidget * entry, const char * uri) +{ + if (! uri || ! uri[0]) + { + gtk_entry_set_text ((GtkEntry *) entry, ""); + return; + } + + StringBuf path = uri_to_filename (uri, false); + gtk_entry_set_text ((GtkEntry *) entry, path ? filename_contract (std::move (path)) : uri); + gtk_editable_set_position ((GtkEditable *) entry, -1); +} + +static void set_label_wrap (GtkWidget * label, void *) +{ + if (GTK_IS_LABEL (label)) + gtk_label_set_line_wrap_mode ((GtkLabel *) label, PANGO_WRAP_WORD_CHAR); +} + +EXPORT GtkWidget * audgui_dialog_new (GtkMessageType type, const char * title, + const char * text, GtkWidget * button1, GtkWidget * button2) +{ + GtkWidget * dialog = gtk_message_dialog_new (nullptr, (GtkDialogFlags) 0, type, + GTK_BUTTONS_NONE, "%s", text); + gtk_window_set_title ((GtkWindow *) dialog, title); + + GtkWidget * box = gtk_message_dialog_get_message_area ((GtkMessageDialog *) dialog); + gtk_container_foreach ((GtkContainer *) box, set_label_wrap, nullptr); + + if (button2) + { + gtk_dialog_add_action_widget ((GtkDialog *) dialog, button2, GTK_RESPONSE_NONE); + g_signal_connect_swapped (button2, "clicked", (GCallback) gtk_widget_destroy, dialog); + } + + gtk_dialog_add_action_widget ((GtkDialog *) dialog, button1, GTK_RESPONSE_NONE); + g_signal_connect_swapped (button1, "clicked", (GCallback) gtk_widget_destroy, dialog); + + gtk_widget_set_can_default (button1, true); + gtk_widget_grab_default (button1); + + return dialog; +} + +EXPORT void audgui_dialog_add_widget (GtkWidget * dialog, GtkWidget * widget) +{ + GtkWidget * box = gtk_message_dialog_get_message_area ((GtkMessageDialog *) dialog); + gtk_box_pack_start ((GtkBox *) box, widget, false, false, 0); +} + +EXPORT void audgui_simple_message (GtkWidget * * widget, GtkMessageType type, + const char * title, const char * text) +{ + if (type == GTK_MESSAGE_ERROR) + AUDERR ("%s\n", text); + else if (type == GTK_MESSAGE_WARNING) + AUDWARN ("%s\n", text); + else if (type == GTK_MESSAGE_INFO) + AUDINFO ("%s\n", text); + + if (* widget) + { + char * old = nullptr; + g_object_get ((GObject *) * widget, "text", & old, nullptr); + g_return_if_fail (old); + + int messages = GPOINTER_TO_INT (g_object_get_data ((GObject *) * widget, "messages")); + if (messages > 10) + text = _("\n(Further messages have been hidden.)"); + + if (! strstr (old, text)) + { + StringBuf both = str_concat ({old, "\n", text}); + g_object_set ((GObject *) * widget, "text", (const char *) both, nullptr); + g_object_set_data ((GObject *) * widget, "messages", GINT_TO_POINTER (messages + 1)); + } + + g_free (old); + gtk_window_present ((GtkWindow *) * widget); + } + else + { + GtkWidget * button = audgui_button_new (_("_Close"), "window-close", nullptr, nullptr); + * widget = audgui_dialog_new (type, title, text, button, nullptr); + + g_object_set_data ((GObject *) * widget, "messages", GINT_TO_POINTER (1)); + g_signal_connect (* widget, "destroy", (GCallback) gtk_widget_destroyed, widget); + + gtk_widget_show_all (* widget); + } +} + +EXPORT cairo_pattern_t * audgui_dark_bg_gradient (const GdkColor & base, int height) +{ + float r = 1, g = 1, b = 1; + + /* in a dark theme, try to match the tone of the base color */ + int v = aud::max (aud::max (base.red, base.green), base.blue); + + if (v >= 10*256 && v < 80*256) + { + r = (float) base.red / v; + g = (float) base.green / v; + b = (float) base.blue / v; + } + + cairo_pattern_t * gradient = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (gradient, 0, 0.16 * r, 0.16 * g, 0.16 * b); + cairo_pattern_add_color_stop_rgb (gradient, 0.45, 0.11 * r, 0.11 * g, 0.11 * b); + cairo_pattern_add_color_stop_rgb (gradient, 0.55, 0.06 * r, 0.06 * g, 0.06 * b); + cairo_pattern_add_color_stop_rgb (gradient, 1, 0.09 * r, 0.09 * g, 0.09 * b); + return gradient; +} + +static void rgb_to_hsv (float r, float g, float b, float * h, float * s, float * v) +{ + float max = aud::max (aud::max (r, g), b); + float min = aud::min (aud::min (r, g), b); + + * v = max; + + if (max == min) + { + * h = 0; + * s = 0; + return; + } + + if (r == max) + * h = 1 + (g - b) / (max - min); + else if (g == max) + * h = 3 + (b - r) / (max - min); + else + * h = 5 + (r - g) / (max - min); + + * s = (max - min) / max; +} + +static void hsv_to_rgb (float h, float s, float v, float * r, float * g, float * b) +{ + for (; h >= 2; h -= 2) + { + float * p = r; + r = g; + g = b; + b = p; + } + + if (h < 1) + { + * r = 1; + * g = 0; + * b = 1 - h; + } + else + { + * r = 1; + * g = h - 1; + * b = 0; + } + + * r = v * (1 - s * (1 - * r)); + * g = v * (1 - s * (1 - * g)); + * b = v * (1 - s * (1 - * b)); +} + +EXPORT void audgui_vis_bar_color (const GdkColor & hue, int bar, int n_bars, + float & r, float & g, float & b) +{ + float h, s, v; + rgb_to_hsv (hue.red / 65535.0, hue.green / 65535.0, hue.blue / 65535.0, & h, & s, & v); + + if (s < 0.1) /* monochrome theme? use blue instead */ + h = 4.6; + + s = 1 - 0.9 * bar / (n_bars - 1); + v = 0.75 + 0.25 * bar / (n_bars - 1); + + hsv_to_rgb (h, s, v, & r, & g, & b); +} diff --git a/src/libaudqt/Makefile b/src/libaudqt/Makefile new file mode 100644 index 0000000..2a13170 --- /dev/null +++ b/src/libaudqt/Makefile @@ -0,0 +1,64 @@ +SHARED_LIB = ${LIB_PREFIX}audqt${LIB_SUFFIX} +LIB_MAJOR = 2 +LIB_MINOR = 2 + +SRCS = about-qt.cc \ + art-qt.cc \ + audqt.cc \ + colorbutton.cc \ + eq-preset-qt.cc \ + equalizer-qt.cc \ + file-entry.cc \ + fileopener.cc \ + font-entry.cc \ + images.cc \ + infopopup-qt.cc \ + infowin-qt.cc \ + info-widget.cc \ + log-inspector.cc \ + menu-qt.cc \ + playlist-management.cc \ + plugin-menu-qt.cc \ + prefs-builder.cc \ + prefs-plugin.cc \ + prefs-widget-qt.cc \ + prefs-window-qt.cc \ + prefs-pluginlist-model.cc \ + queue-manager-qt.cc \ + url-opener-qt.cc \ + util-qt.cc \ + treeview.cc \ + volumebutton.cc + +INCLUDES = colorbutton.h \ + export.h \ + iface.h \ + info-widget.h \ + libaudqt.h \ + menu.h \ + treeview.h + +CLEAN = images.cc + +include ../../buildsys.mk +include ../../extra.mk + +includesubdir = libaudqt + +LD = ${CXX} + +CPPFLAGS := -I.. -I../.. \ + ${CPPFLAGS} \ + ${QT_CFLAGS} \ + -DLIBAUDQT_BUILD + +CFLAGS += ${LIB_CFLAGS} + +LIB_LDFLAGS := -L../libaudcore $(LIB_LDFLAGS) + +LIBS := -laudcore \ + ${LIBS} -lm \ + ${QT_LIBS} + +images.cc: images.qrc + ${QT_BINPATH}/rcc images.qrc -o images.cc diff --git a/src/libaudqt/about-qt.cc b/src/libaudqt/about-qt.cc new file mode 100644 index 0000000..a80fd33 --- /dev/null +++ b/src/libaudqt/about-qt.cc @@ -0,0 +1,107 @@ +/* + * about.cc + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <QDialog> +#include <QLabel> +#include <QPlainTextEdit> +#include <QPointer> +#include <QTabWidget> +#include <QVBoxLayout> + +#include <libaudcore/audstrings.h> +#include <libaudcore/i18n.h> +#include <libaudcore/runtime.h> +#include <libaudcore/vfs.h> + +#include "libaudqt.h" + +static QTabWidget * buildCreditsNotebook(QWidget * parent) +{ + const char * data_dir = aud_get_path(AudPath::DataDir); + const char * titles[2] = {N_("Credits"), N_("License")}; + const char * filenames[2] = {"AUTHORS", "COPYING"}; + + auto tabs = new QTabWidget(parent); + tabs->setDocumentMode(true); + tabs->setMinimumSize(6 * audqt::sizes.OneInch, 2 * audqt::sizes.OneInch); + + for (int i = 0; i < 2; i++) + { + auto text = VFSFile::read_file(filename_build({data_dir, filenames[i]}), + VFS_APPEND_NULL); + auto edit = new QPlainTextEdit(text.begin(), parent); + edit->setReadOnly(true); + edit->setFrameStyle(QFrame::NoFrame); + tabs->addTab(edit, _(titles[i])); + } + + return tabs; +} + +static QDialog * buildAboutWindow() +{ + const char * about_text = + "<big><b>Audacious " VERSION "</b></big><br>" COPYRIGHT; + const char * website = "https://audacious-media-player.org"; + + auto window = new QDialog; + window->setWindowTitle(_("About Audacious")); + + auto logo = new QLabel(window); + int logo_size = audqt::to_native_dpi(400); + logo->setPixmap(QIcon(":/about-logo.svg").pixmap(logo_size, logo_size)); + logo->setAlignment(Qt::AlignHCenter); + + auto text = new QLabel(about_text, window); + text->setAlignment(Qt::AlignHCenter); + + auto anchor = QString("<a href='%1'>%1</a>").arg(website); + auto link_label = new QLabel(anchor, window); + link_label->setAlignment(Qt::AlignHCenter); + link_label->setOpenExternalLinks(true); + + auto layout = audqt::make_vbox(window); + layout->addSpacing(audqt::sizes.EightPt); + layout->addWidget(logo); + layout->addWidget(text); + layout->addWidget(link_label); + layout->addWidget(buildCreditsNotebook(window)); + + return window; +} + +static QPointer<QDialog> s_aboutwin; + +namespace audqt +{ + +EXPORT void aboutwindow_show() +{ + if (!s_aboutwin) + { + s_aboutwin = buildAboutWindow(); + s_aboutwin->setAttribute(Qt::WA_DeleteOnClose); + } + + window_bring_to_front(s_aboutwin); +} + +EXPORT void aboutwindow_hide() { delete s_aboutwin; } + +} // namespace audqt diff --git a/src/libaudqt/art-qt.cc b/src/libaudqt/art-qt.cc new file mode 100644 index 0000000..3c3bad9 --- /dev/null +++ b/src/libaudqt/art-qt.cc @@ -0,0 +1,82 @@ +/* + * art.cc + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <QApplication> +#include <QIcon> +#include <QImage> +#include <QPixmap> + +#include <libaudcore/audstrings.h> +#include <libaudcore/drct.h> +#include <libaudcore/probe.h> +#include <libaudcore/runtime.h> +#include <libaudqt/libaudqt.h> + +namespace audqt +{ + +EXPORT QImage art_request(const char * filename, bool * queued) +{ + AudArtPtr art = aud_art_request(filename, AUD_ART_DATA, queued); + + auto data = art.data(); + return data ? QImage::fromData((const uchar *)data->begin(), data->len()) + : QImage(); +} + +EXPORT QPixmap art_scale(const QImage & image, unsigned int w, unsigned int h, + bool want_hidpi) +{ + // return original image if requested size is zero, + // or original size is smaller than requested size + if ((w == 0 && h == 0) || + ((unsigned)image.width() <= w && (unsigned)image.height() <= h)) + return QPixmap::fromImage(image); + + qreal r = want_hidpi ? qApp->devicePixelRatio() : 1; + auto pixmap = QPixmap::fromImage(image.scaled( + w * r, h * r, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + + pixmap.setDevicePixelRatio(r); + return pixmap; +} + +EXPORT QPixmap art_request(const char * filename, unsigned int w, + unsigned int h, bool want_hidpi) +{ + auto img = art_request(filename); + if (!img.isNull()) + return art_scale(img, w, h, want_hidpi); + + unsigned size = to_native_dpi(48); + return get_icon("audio-x-generic") + .pixmap(aud::min(w, size), aud::min(h, size)); +} + +EXPORT QPixmap art_request_current(unsigned int w, unsigned int h, + bool want_hidpi) +{ + String filename = aud_drct_get_filename(); + if (!filename) + return QPixmap(); + + return art_request(filename, w, h, want_hidpi); +} + +} // namespace audqt diff --git a/src/libaudqt/audqt.cc b/src/libaudqt/audqt.cc new file mode 100644 index 0000000..a5d3e95 --- /dev/null +++ b/src/libaudqt/audqt.cc @@ -0,0 +1,247 @@ +/* + * util.cc + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stdlib.h> + +#include <QApplication> +#include <QDesktopWidget> +#include <QPushButton> +#include <QVBoxLayout> + +#include <libaudcore/audstrings.h> +#include <libaudcore/i18n.h> +#include <libaudcore/runtime.h> + +#include "libaudqt-internal.h" +#include "libaudqt.h" + +namespace audqt +{ + +static int init_count; + +static PixelSizes sizes_local; +static PixelMargins margins_local; + +EXPORT const PixelSizes & sizes = sizes_local; +EXPORT const PixelMargins & margins = margins_local; + +EXPORT void init() +{ + if (init_count++) + return; + + static char app_name[] = "audacious"; + static int dummy_argc = 1; + static char * dummy_argv[] = {app_name, nullptr}; + + auto qapp = new QApplication(dummy_argc, dummy_argv); + + qapp->setAttribute(Qt::AA_UseHighDpiPixmaps); +#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) + qapp->setAttribute(Qt::AA_ForceRasterWidgets); +#endif +#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0) + qapp->setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles); +#endif + + qapp->setApplicationName(_("Audacious")); + if (qapp->windowIcon().isNull()) + qapp->setWindowIcon(audqt::get_icon(app_name)); + + qapp->setQuitOnLastWindowClosed(false); + + auto desktop = qapp->desktop(); + sizes_local.OneInch = + aud::max(96, (desktop->logicalDpiX() + desktop->logicalDpiY()) / 2); + sizes_local.TwoPt = aud::rescale(2, 72, sizes_local.OneInch); + sizes_local.FourPt = aud::rescale(4, 72, sizes_local.OneInch); + sizes_local.EightPt = aud::rescale(8, 72, sizes_local.OneInch); + + margins_local.TwoPt = + QMargins(sizes.TwoPt, sizes.TwoPt, sizes.TwoPt, sizes.TwoPt); + margins_local.FourPt = + QMargins(sizes.FourPt, sizes.FourPt, sizes.FourPt, sizes.FourPt); + margins_local.EightPt = + QMargins(sizes.EightPt, sizes.EightPt, sizes.EightPt, sizes.EightPt); + +#ifdef Q_OS_MAC // Mac-specific font tweaks + QApplication::setFont(QApplication::font("QSmallFont"), "QDialog"); + QApplication::setFont(QApplication::font("QSmallFont"), "QTreeView"); + QApplication::setFont(QApplication::font("QTipLabel"), "QStatusBar"); +#endif + + log_init(); +} + +EXPORT void run() { qApp->exec(); } + +EXPORT void quit() { qApp->quit(); } + +EXPORT void cleanup() +{ + if (--init_count) + return; + + aboutwindow_hide(); + eq_presets_hide(); + equalizer_hide(); + infopopup_hide_now(); + infowin_hide(); + log_inspector_hide(); + plugin_prefs_hide(); + prefswin_hide(); + queue_manager_hide(); + + log_cleanup(); + + delete qApp; +} + +EXPORT QIcon get_icon(const char * name) +{ + auto icon = QIcon::fromTheme(name); + + if (icon.isNull()) + icon = QIcon(QString(":/") + name + ".svg"); + + return icon; +} + +EXPORT QGradientStops dark_bg_gradient(const QColor & base) +{ + constexpr int s[4] = {40, 28, 16, 24}; + + QColor c[4]; + for (int i = 0; i < 4; i++) + c[i] = QColor(s[i], s[i], s[i]); + + /* in a dark theme, try to match the tone of the base color */ + int v = base.value(); + if (v >= 10 && v < 80) + { + int r = base.red(), g = base.green(), b = base.blue(); + + for (int i = 0; i < 4; i++) + { + c[i] = QColor(r * s[i] / v, g * s[i] / v, b * s[i] / v); + } + } + + return {{0, c[0]}, {0.45, c[1]}, {0.55, c[2]}, {1, c[3]}}; +} + +EXPORT QColor vis_bar_color(const QColor & hue, int bar, int n_bars) +{ + qreal h, s, v; + hue.getHsvF(&h, &s, &v); + + if (s < 0.1) /* monochrome? use blue instead */ + h = 0.67; + + s = 1 - 0.9 * bar / (n_bars - 1); + v = 0.75 + 0.25 * bar / (n_bars - 1); + + return QColor::fromHsvF(h, s, v); +} + +EXPORT QHBoxLayout * make_hbox(QWidget * parent, int spacing) +{ + auto layout = new QHBoxLayout(parent); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(spacing); + return layout; +} + +EXPORT QVBoxLayout * make_vbox(QWidget * parent, int spacing) +{ + auto layout = new QVBoxLayout(parent); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(spacing); + return layout; +} + +EXPORT void enable_layout(QLayout * layout, bool enabled) +{ + int count = layout->count(); + for (int i = 0; i < count; i++) + { + auto item = layout->itemAt(i); + if (QLayout * layout2 = item->layout()) + enable_layout(layout2, enabled); + if (QWidget * widget = item->widget()) + widget->setEnabled(enabled); + } +} + +EXPORT void clear_layout(QLayout * layout) +{ + while (QLayoutItem * item = layout->takeAt(0)) + { + if (QLayout * layout2 = item->layout()) + clear_layout(layout2); + if (QWidget * widget = item->widget()) + delete widget; + + delete item; + } +} + +/* the goal is to force a window to come to the front on any Qt platform */ +EXPORT void window_bring_to_front(QWidget * window) +{ + window->show(); + + Qt::WindowStates state = window->windowState(); + + state &= ~Qt::WindowMinimized; + state |= Qt::WindowActive; + + window->setWindowState(state); + window->raise(); + window->activateWindow(); +} + +EXPORT void simple_message(const char * title, const char * text) +{ + simple_message(title, text, QMessageBox::NoIcon); +} + +EXPORT void simple_message(const char * title, const char * text, + QMessageBox::Icon icon) +{ + auto msgbox = new QMessageBox(icon, title, text, QMessageBox::Close); + msgbox->button(QMessageBox::Close)->setText(translate_str(N_("_Close"))); + msgbox->setAttribute(Qt::WA_DeleteOnClose); + msgbox->setTextInteractionFlags(Qt::TextSelectableByMouse); + msgbox->show(); +} + +/* translate GTK+ accelerators and also handle dgettext() */ +EXPORT QString translate_str(const char * str, const char * domain) +{ + /* handle null and empty strings */ + if (!str || !str[0]) + return QString(str); + + /* translate the GTK+ accelerator (_) into a Qt accelerator (&) */ + return QString(dgettext(domain, str)).replace('_', '&'); +} + +} // namespace audqt diff --git a/src/libaudqt/colorbutton.cc b/src/libaudqt/colorbutton.cc new file mode 100644 index 0000000..a3d631a --- /dev/null +++ b/src/libaudqt/colorbutton.cc @@ -0,0 +1,62 @@ +/* + * colorbutton.h + * Copyright 2019 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "colorbutton.h" +#include "libaudqt.h" + +#include <QColorDialog> +#include <QPainter> + +namespace audqt +{ + +ColorButton::ColorButton(QWidget * parent) : QPushButton(parent) +{ + connect(this, &QPushButton::clicked, [this]() { + auto dialog = findChild<QColorDialog *>(); + if (!dialog) + { + dialog = new QColorDialog(m_color, this); + dialog->setAttribute(Qt::WA_DeleteOnClose); + connect(dialog, &QColorDialog::colorSelected, this, + &ColorButton::setColor); + } + + window_bring_to_front(dialog); + }); +} + +void ColorButton::setColor(const QColor & color) +{ + if (color != m_color) + { + m_color = color; + update(); + + onColorChanged(); + } +} + +void ColorButton::paintEvent(QPaintEvent * event) +{ + QPushButton::paintEvent(event); + QPainter(this).fillRect(rect() - margins.FourPt, m_color); +} + +} // namespace audqt diff --git a/src/libaudqt/colorbutton.h b/src/libaudqt/colorbutton.h new file mode 100644 index 0000000..da8803b --- /dev/null +++ b/src/libaudqt/colorbutton.h @@ -0,0 +1,52 @@ +/* + * colorbutton.h + * Copyright 2019 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDQT_COLORBUTTON_H +#define LIBAUDQT_COLORBUTTON_H + +#include "libaudqt/export.h" + +#include <QColor> +#include <QPushButton> + +namespace audqt +{ + +class LIBAUDQT_PUBLIC ColorButton : public QPushButton +{ +public: + ColorButton(QWidget * parent = nullptr); + ~ColorButton(){}; + + void setColor(const QColor &); + + QColor color() const { return m_color; } + +protected: + virtual void onColorChanged(){}; + +private: + void paintEvent(QPaintEvent *) override; + + QColor m_color; +}; + +} // namespace audqt + +#endif diff --git a/src/libaudqt/eq-preset-qt.cc b/src/libaudqt/eq-preset-qt.cc new file mode 100644 index 0000000..33f2196 --- /dev/null +++ b/src/libaudqt/eq-preset-qt.cc @@ -0,0 +1,414 @@ +/* + * eq-preset-qt.cc + * Copyright 2018 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt.h" +#include "treeview.h" + +#include <QBoxLayout> +#include <QDialog> +#include <QLineEdit> +#include <QPointer> +#include <QPushButton> +#include <QStandardItemModel> + +#include "libaudcore/audstrings.h" +#include "libaudcore/equalizer.h" +#include "libaudcore/i18n.h" +#include "libaudcore/interface.h" +#include "libaudcore/runtime.h" +#include "libaudcore/vfs.h" + +namespace audqt +{ + +class PresetItem : public QStandardItem +{ +public: + explicit PresetItem(const EqualizerPreset & preset) + : QStandardItem((const char *)preset.name), preset(preset) + { + } + + const EqualizerPreset preset; +}; + +class PresetModel : public QStandardItemModel +{ +public: + explicit PresetModel(QObject * parent) : QStandardItemModel(0, 1, parent) {} + + void load_all(); + void save_all(); + + QModelIndex add_preset(const EqualizerPreset & preset); + QModelIndex add_preset(const char * name); + void apply_preset(int row); + + const EqualizerPreset * preset_at(int row) const + { + auto pitem = static_cast<PresetItem *>(item(row)); + return pitem ? &pitem->preset : nullptr; + } + + bool removeRows(int row, int count, + const QModelIndex & parent = QModelIndex()) override + { + bool removed = QStandardItemModel::removeRows(row, count, parent); + m_changed = m_changed || removed; + return removed; + } + +private: + bool m_changed = false; +}; + +void PresetModel::load_all() +{ + clear(); + + auto presets = aud_eq_read_presets("eq.preset"); + for (const EqualizerPreset & preset : presets) + appendRow(new PresetItem(preset)); + + m_changed = false; +} + +void PresetModel::save_all() +{ + if (!m_changed) + return; + + Index<EqualizerPreset> presets; + for (int row = 0; row < rowCount(); row++) + presets.append(*preset_at(row)); + + presets.sort([](const EqualizerPreset & a, const EqualizerPreset & b) { + return strcmp(a.name, b.name); + }); + + aud_eq_write_presets(presets, "eq.preset"); + m_changed = false; +} + +QModelIndex PresetModel::add_preset(const EqualizerPreset & preset) +{ + int insert_idx = rowCount(); + for (int row = 0; row < rowCount(); row++) + { + if (preset_at(row)->name == preset.name) + { + insert_idx = row; + break; + } + } + + setItem(insert_idx, new PresetItem(preset)); + m_changed = true; + + return index(insert_idx, 0); +} + +QModelIndex PresetModel::add_preset(const char * name) +{ + EqualizerPreset preset{String(name)}; + aud_eq_update_preset(preset); + return add_preset(preset); +} + +void PresetModel::apply_preset(int row) +{ + auto preset = preset_at(row); + if (!preset) + return; + + aud_eq_apply_preset(*preset); + aud_set_bool("equalizer_active", true); +} + +class PresetView : public TreeView +{ +public: + PresetView(QPushButton * export_btn) : m_export_btn(export_btn) + { + setEditTriggers(QTreeView::NoEditTriggers); + setHeaderHidden(true); + setIndentation(0); + setSelectionMode(QTreeView::ExtendedSelection); + setUniformRowHeights(true); + + auto pmodel = new PresetModel(this); + pmodel->load_all(); + setModel(pmodel); + } + + PresetModel * pmodel() const { return static_cast<PresetModel *>(model()); } + + void add_imported(const Index<EqualizerPreset> & presets); + + const EqualizerPreset * preset_for_export() const + { + auto idxs = selectionModel()->selectedIndexes(); + if (idxs.size() != 1) + return nullptr; + + return pmodel()->preset_at(idxs[0].row()); + } + +protected: + void activate(const QModelIndex & index) override + { + pmodel()->apply_preset(index.row()); + } + + void selectionChanged(const QItemSelection & selected, + const QItemSelection & deselected) override + { + TreeView::selectionChanged(selected, deselected); + + auto idxs = selectionModel()->selectedIndexes(); + m_export_btn->setEnabled(idxs.size() == 1); + } + +private: + QPushButton * m_export_btn; +}; + +void PresetView::add_imported(const Index<EqualizerPreset> & presets) +{ + QItemSelection sel; + for (auto & preset : presets) + { + auto idx = pmodel()->add_preset(preset); + sel.select(idx, idx); + } + + selectionModel()->select(sel, QItemSelectionModel::Clear | + QItemSelectionModel::SelectCurrent); + + if (presets.len() == 1) + { + aud_eq_apply_preset(presets[0]); + aud_set_bool("equalizer_active", true); + } +} + +static Index<EqualizerPreset> import_file(const char * filename) +{ + VFSFile file(filename, "r"); + if (!file) + return Index<EqualizerPreset>(); + + if (str_has_suffix_nocase(filename, ".eqf") || + str_has_suffix_nocase(filename, ".q1")) + { + return aud_import_winamp_presets(file); + } + + /* assume everything else is a native preset file */ + Index<EqualizerPreset> presets; + presets.append(); + + if (!aud_load_preset_file(presets[0], file)) + presets.clear(); + + return presets; +} + +static bool export_file(const char * filename, const EqualizerPreset & preset) +{ + VFSFile file(filename, "w"); + if (!file) + return false; + + if (str_has_suffix_nocase(filename, ".eqf") || + str_has_suffix_nocase(filename, ".q1")) + { + return aud_export_winamp_preset(preset, file); + } + + /* assume everything else is a native preset file */ + return aud_save_preset_file(preset, file); +} + +static const char * name_filter = N_("Preset files (*.preset *.eqf *.q1)"); + +static void show_import_dialog(QDialog * parent, PresetView * view) +{ + auto dialog = new QFileDialog(parent, _("Load Preset File")); + + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setFileMode(QFileDialog::ExistingFile); + dialog->setLabelText(QFileDialog::Accept, _("Load")); + dialog->setNameFilter(_(name_filter)); + + QObject::connect(dialog, &QFileDialog::accepted, [dialog, view]() { + auto urls = dialog->selectedUrls(); + if (urls.size() != 1) + return; + + auto filename = urls[0].toEncoded(); + auto presets = import_file(filename); + + if (presets.len()) + { + view->add_imported(presets); + dialog->deleteLater(); + } + else + { + aud_ui_show_error( + str_printf(_("Error loading %s."), filename.constData())); + } + }); + + window_bring_to_front(dialog); +} + +static void show_export_dialog(QDialog * parent, const EqualizerPreset & preset) +{ + auto dialog = new QFileDialog(parent, _("Save Preset File")); + + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setAcceptMode(QFileDialog::AcceptSave); + dialog->setFileMode(QFileDialog::AnyFile); + dialog->setLabelText(QFileDialog::Accept, _("Save")); + dialog->setNameFilter(_(name_filter)); + + /* TODO: replace other illegal characters on Win32 */ + auto safe = + QString(preset.name).replace(QLatin1Char('/'), QLatin1Char('_')); + dialog->selectFile(safe + ".preset"); + + QObject::connect(dialog, &QFileDialog::accepted, [dialog, preset]() { + auto urls = dialog->selectedUrls(); + if (urls.size() != 1) + return; + + auto filename = urls[0].toEncoded(); + + if (export_file(filename, preset)) + dialog->deleteLater(); + else + aud_ui_show_error( + str_printf(_("Error saving %s."), filename.constData())); + }); + + window_bring_to_front(dialog); +} + +static QDialog * create_preset_win() +{ + auto win = new QDialog; + win->setAttribute(Qt::WA_DeleteOnClose); + win->setWindowTitle(_("Equalizer Presets")); + win->setContentsMargins(margins.TwoPt); + + auto edit = new QLineEdit; + auto save_btn = new QPushButton(_("Save Preset")); + save_btn->setIcon(get_icon("document-save")); + save_btn->setDisabled(true); + + auto hbox = make_hbox(nullptr); + hbox->addWidget(edit); + hbox->addWidget(save_btn); + + auto import_btn = new QPushButton(_("Import")); + import_btn->setIcon(get_icon("document-open")); + + auto export_btn = new QPushButton(_("Export")); + export_btn->setIcon(get_icon("document-save")); + + auto view = new PresetView(export_btn); + + auto hbox2 = make_hbox(nullptr); + hbox2->addWidget(import_btn); + hbox2->addWidget(export_btn); + hbox2->addStretch(1); + + auto revert_btn = new QPushButton(_("Revert Changes")); + revert_btn->setIcon(get_icon("edit-undo")); + revert_btn->setDisabled(true); + + auto close_btn = new QPushButton(_("Close")); + close_btn->setIcon(get_icon("window-close")); + + auto hbox3 = make_hbox(nullptr); + hbox3->addWidget(revert_btn); + hbox3->addStretch(1); + hbox3->addWidget(close_btn); + + auto vbox = make_vbox(win); + vbox->addLayout(hbox); + vbox->addWidget(view); + vbox->addLayout(hbox2); + vbox->addLayout(hbox3); + + auto pmodel = view->pmodel(); + + QObject::connect(edit, &QLineEdit::textChanged, + [save_btn](const QString & text) { + save_btn->setEnabled(!text.isEmpty()); + }); + + QObject::connect(save_btn, &QPushButton::clicked, + [view, pmodel, edit, revert_btn]() { + auto added = pmodel->add_preset(edit->text().toUtf8()); + view->setCurrentIndex(added); + revert_btn->setDisabled(false); + }); + + QObject::connect(import_btn, &QPushButton::clicked, + [win, view]() { show_import_dialog(win, view); }); + + QObject::connect(export_btn, &QPushButton::clicked, [win, view]() { + auto preset = view->preset_for_export(); + if (preset != nullptr) + show_export_dialog(win, *preset); + }); + + QObject::connect(pmodel, &PresetModel::rowsRemoved, + [revert_btn]() { revert_btn->setDisabled(false); }); + + QObject::connect(revert_btn, &QPushButton::clicked, [pmodel, revert_btn]() { + pmodel->load_all(); + revert_btn->setDisabled(true); + }); + + QObject::connect(close_btn, &QPushButton::clicked, win, + &QObject::deleteLater); + + QObject::connect(win, &QObject::destroyed, + [pmodel]() { pmodel->save_all(); }); + + return win; +} + +static QPointer<QDialog> s_preset_win; + +EXPORT void eq_presets_show() +{ + if (!s_preset_win) + s_preset_win = create_preset_win(); + + window_bring_to_front(s_preset_win); +} + +EXPORT void eq_presets_hide() { delete s_preset_win; } + +} // namespace audqt diff --git a/src/libaudqt/equalizer-qt.cc b/src/libaudqt/equalizer-qt.cc new file mode 100644 index 0000000..5458bf4 --- /dev/null +++ b/src/libaudqt/equalizer-qt.cc @@ -0,0 +1,220 @@ +/* + * equalizer.cc + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <QCheckBox> +#include <QDialog> +#include <QFrame> +#include <QHBoxLayout> +#include <QLabel> +#include <QPainter> +#include <QPointer> +#include <QPushButton> +#include <QSlider> +#include <QStyle> +#include <QVBoxLayout> + +#include <libaudcore/equalizer.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/runtime.h> + +#include "libaudqt.h" + +class VLabel : public QLabel +{ +public: + VLabel(const QString & text, QWidget * parent = nullptr) + : QLabel(text, parent) + { + } + + QSize minimumSizeHint() const + { + QSize s = QLabel::minimumSizeHint(); + return QSize(s.height(), s.width()); + } + + QSize sizeHint() const + { + QSize s = QLabel::sizeHint(); + return QSize(s.height(), s.width()); + } + + void paintEvent(QPaintEvent *) + { + QPainter p(this); + p.rotate(270); + + QRect box(-height(), 0, height(), width()); + style()->drawItemText(&p, box, (int)alignment(), palette(), isEnabled(), + text(), QPalette::Foreground); + } +}; + +class EqualizerSlider : public QWidget +{ +public: + QSlider slider; + + EqualizerSlider(const char * label, QWidget * parent) + : QWidget(parent), slider(Qt::Vertical) + { + slider.setMinimumHeight(audqt::sizes.OneInch); + slider.setRange(-AUD_EQ_MAX_GAIN, AUD_EQ_MAX_GAIN); + slider.setTickInterval(AUD_EQ_MAX_GAIN >> 1); + slider.setTickPosition(QSlider::TicksBothSides); + + auto layout = audqt::make_vbox(this); + auto value_label = new QLabel("0"); + + layout->addWidget(new VLabel(label, this), 1, Qt::AlignCenter); + layout->addWidget(&slider, 0, Qt::AlignCenter); + layout->addWidget(value_label, 0, Qt::AlignCenter); + + connect(&slider, &QSlider::valueChanged, [value_label](int value) { + value_label->setText(QString::number(value)); + }); + } +}; + +class EqualizerWindow : public QDialog +{ +public: + EqualizerWindow(); + +private: + QCheckBox m_onoff_checkbox; + EqualizerSlider * m_preamp_slider; + EqualizerSlider * m_sliders[AUD_EQ_NBANDS]; + + void updateActive(); + void updatePreamp(); + void updateBands(); + + const HookReceiver<EqualizerWindow> hook1{"set equalizer_active", this, + &EqualizerWindow::updateActive}, + hook2{"set equalizer_preamp", this, &EqualizerWindow::updatePreamp}, + hook3{"set equalizer_bands", this, &EqualizerWindow::updateBands}; +}; + +EqualizerWindow::EqualizerWindow() + : m_onoff_checkbox(audqt::translate_str(N_("_Enable"))) +{ + const char * const names[AUD_EQ_NBANDS] = { + N_("31 Hz"), N_("63 Hz"), N_("125 Hz"), N_("250 Hz"), N_("500 Hz"), + N_("1 kHz"), N_("2 kHz"), N_("4 kHz"), N_("8 kHz"), N_("16 kHz")}; + + auto slider_container = new QWidget(this); + auto slider_layout = audqt::make_hbox(slider_container, audqt::sizes.TwoPt); + + m_preamp_slider = new EqualizerSlider(_("Preamp"), this); + slider_layout->addWidget(m_preamp_slider); + + auto line = new QFrame(this); + line->setFrameShape(QFrame::VLine); + line->setFrameShadow(QFrame::Sunken); + slider_layout->addWidget(line); + + for (int i = 0; i < AUD_EQ_NBANDS; i++) + { + m_sliders[i] = new EqualizerSlider(_(names[i]), this); + slider_layout->addWidget(m_sliders[i]); + } + + auto zero_button = new QPushButton(_("Reset to Zero"), this); + auto preset_button = new QPushButton(_("Presets ..."), this); + + auto hbox = audqt::make_hbox(nullptr); + hbox->addWidget(&m_onoff_checkbox); + hbox->addStretch(1); + hbox->addWidget(zero_button); + hbox->addWidget(preset_button); + + auto layout = audqt::make_vbox(this); + layout->setSizeConstraint(QLayout::SetFixedSize); + layout->addLayout(hbox); + layout->addWidget(slider_container); + + setWindowTitle(_("Equalizer")); + setContentsMargins(audqt::margins.EightPt); + + m_onoff_checkbox.setFocus(); + + updateActive(); + updatePreamp(); + updateBands(); + + connect(&m_onoff_checkbox, &QCheckBox::stateChanged, [](int state) { + aud_set_bool("equalizer_active", (state == Qt::Checked)); + }); + + connect(zero_button, &QPushButton::clicked, + []() { aud_eq_apply_preset(EqualizerPreset()); }); + + connect(preset_button, &QPushButton::clicked, audqt::eq_presets_show); + + connect(&m_preamp_slider->slider, &QSlider::valueChanged, + [](int value) { aud_set_int("equalizer_preamp", value); }); + + for (int i = 0; i < AUD_EQ_NBANDS; i++) + { + connect(&m_sliders[i]->slider, &QSlider::valueChanged, + [i](int value) { aud_eq_set_band(i, value); }); + } +} + +void EqualizerWindow::updateActive() +{ + bool active = aud_get_bool("equalizer_active"); + m_onoff_checkbox.setCheckState(active ? Qt::Checked : Qt::Unchecked); +} + +void EqualizerWindow::updatePreamp() +{ + m_preamp_slider->slider.setValue(aud_get_int("equalizer_preamp")); +} + +void EqualizerWindow::updateBands() +{ + double values[AUD_EQ_NBANDS]; + aud_eq_get_bands(values); + + for (int i = 0; i < AUD_EQ_NBANDS; i++) + m_sliders[i]->slider.setValue(values[i]); +} + +static QPointer<EqualizerWindow> s_equalizer; + +namespace audqt +{ + +EXPORT void equalizer_show() +{ + if (!s_equalizer) + { + s_equalizer = new EqualizerWindow; + s_equalizer->setAttribute(Qt::WA_DeleteOnClose); + } + + window_bring_to_front(s_equalizer); +} + +EXPORT void equalizer_hide() { delete s_equalizer; } + +} // namespace audqt diff --git a/src/libaudqt/export.h b/src/libaudqt/export.h new file mode 100644 index 0000000..8662a73 --- /dev/null +++ b/src/libaudqt/export.h @@ -0,0 +1,33 @@ +/* + * export.h + * Copyright 2016 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDQT_EXPORT_H +#define LIBAUDQT_EXPORT_H + +#ifdef _WIN32 +#ifdef LIBAUDQT_BUILD +#define LIBAUDQT_PUBLIC __declspec(dllexport) +#else +#define LIBAUDQT_PUBLIC __declspec(dllimport) +#endif +#else +#define LIBAUDQT_PUBLIC __attribute__((visibility("default"))) +#endif + +#endif // LIBAUDQT_EXPORT_H diff --git a/src/libaudqt/file-entry.cc b/src/libaudqt/file-entry.cc new file mode 100644 index 0000000..9c04068 --- /dev/null +++ b/src/libaudqt/file-entry.cc @@ -0,0 +1,128 @@ +/* + * file-entry.cc + * Copyright 2018 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt.h" + +#include <QAction> +#include <QLineEdit> +#include <QPointer> + +#include <libaudcore/audstrings.h> +#include <libaudcore/i18n.h> + +namespace audqt +{ + +class FileEntry : public QLineEdit +{ +public: + FileEntry(QWidget * parent, const char * title, + QFileDialog::FileMode file_mode, + QFileDialog::AcceptMode accept_mode) + : QLineEdit(parent), m_title(title), m_file_mode(file_mode), + m_accept_mode(accept_mode), + m_action(get_icon("document-open"), _("Browse"), nullptr) + { + addAction(&m_action, TrailingPosition); + connect(&m_action, &QAction::triggered, this, &FileEntry::show_dialog); + } + +private: + QFileDialog * create_dialog(); + void show_dialog(); + + const QString m_title; + const QFileDialog::FileMode m_file_mode; + const QFileDialog::AcceptMode m_accept_mode; + + QAction m_action; + QPointer<QFileDialog> m_dialog; +}; + +QFileDialog * FileEntry::create_dialog() +{ + auto dialog = new QFileDialog(this, m_title); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setFileMode(m_file_mode); + dialog->setAcceptMode(m_accept_mode); + + String uri = file_entry_get_uri(this); + if (uri) + { + // As of Qt 5.11, selectUrl() works fine with the built-in Qt dialog + // but has no effect on the GTK-based dialog. As a workaround, try to + // get a local file path and use selectFile() instead. + StringBuf local = uri_to_filename(uri); + if (local) + dialog->selectFile((const char *)local); + else + dialog->selectUrl(QUrl((const char *)uri)); + } + + QObject::connect(dialog, &QFileDialog::accepted, [this, dialog]() { + auto urls = dialog->selectedUrls(); + if (urls.length() == 1) + file_entry_set_uri(this, urls[0].toEncoded().constData()); + }); + + return dialog; +} + +void FileEntry::show_dialog() +{ + if (!m_dialog) + m_dialog = create_dialog(); + + window_bring_to_front(m_dialog); +} + +EXPORT QLineEdit * file_entry_new(QWidget * parent, const char * title, + QFileDialog::FileMode file_mode, + QFileDialog::AcceptMode accept_mode) +{ + return new FileEntry(parent, title, file_mode, accept_mode); +} + +EXPORT String file_entry_get_uri(QLineEdit * entry) +{ + QByteArray text = entry->text().toUtf8(); + + if (text.isEmpty()) + return String(); + else if (strstr(text, "://")) + return String(text); + else + return String(filename_to_uri( + filename_normalize(filename_expand(str_copy(text))))); +} + +EXPORT void file_entry_set_uri(QLineEdit * entry, const char * uri) +{ + if (!uri || !uri[0]) + { + entry->clear(); + return; + } + + StringBuf path = uri_to_filename(uri, false); + entry->setText(path ? filename_contract(std::move(path)) : uri); + entry->end(false); +} + +} // namespace audqt diff --git a/src/libaudqt/fileopener.cc b/src/libaudqt/fileopener.cc new file mode 100644 index 0000000..de2173e --- /dev/null +++ b/src/libaudqt/fileopener.cc @@ -0,0 +1,123 @@ +/* + * fileopener.cc + * Copyright 2014 Michał Lipski + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <QFileDialog> +#include <QPointer> + +#include <libaudcore/drct.h> +#include <libaudcore/i18n.h> +#include <libaudcore/playlist.h> +#include <libaudcore/runtime.h> + +#include <libaudqt/libaudqt.h> + +namespace audqt +{ + +static aud::array<FileMode, QPointer<QFileDialog>> s_dialogs; + +static void import_playlist(Playlist playlist, const String & filename) +{ + playlist.set_filename(filename); + playlist.remove_all_entries(); + playlist.insert_entry(0, filename, Tuple(), false); +} + +static void export_playlist(Playlist playlist, const String & filename) +{ + Playlist::GetMode mode = Playlist::Wait; + if (aud_get_bool("metadata_on_play")) + mode = Playlist::NoWait; + + playlist.set_filename(filename); + playlist.save_to_file(filename, mode); +} + +EXPORT void fileopener_show(FileMode mode) +{ + QPointer<QFileDialog> & dialog = s_dialogs[mode]; + + if (!dialog) + { + static constexpr aud::array<FileMode, const char *> titles{ + N_("Open Files"), N_("Open Folder"), N_("Add Files"), + N_("Add Folder"), N_("Import Playlist"), N_("Export Playlist")}; + + static constexpr aud::array<FileMode, const char *> labels{ + N_("Open"), N_("Open"), N_("Add"), + N_("Add"), N_("Import"), N_("Export")}; + + static constexpr aud::array<FileMode, QFileDialog::FileMode> modes{ + QFileDialog::ExistingFiles, QFileDialog::Directory, + QFileDialog::ExistingFiles, QFileDialog::Directory, + QFileDialog::ExistingFile, QFileDialog::AnyFile}; + + String path = aud_get_str("audgui", "filesel_path"); + dialog = new QFileDialog(nullptr, _(titles[mode]), QString(path)); + + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setFileMode(modes[mode]); + dialog->setLabelText(QFileDialog::Accept, _(labels[mode])); + + if (mode == FileMode::ExportPlaylist) + dialog->setAcceptMode(QFileDialog::AcceptSave); + + QObject::connect(dialog.data(), &QFileDialog::directoryEntered, + [](const QString & path) { + aud_set_str("audgui", "filesel_path", + path.toUtf8().constData()); + }); + + auto playlist = Playlist::active_playlist(); + + QObject::connect( + dialog.data(), &QFileDialog::accepted, [dialog, mode, playlist]() { + Index<PlaylistAddItem> files; + for (const QUrl & url : dialog->selectedUrls()) + files.append(String(url.toEncoded().constData())); + + switch (mode) + { + case FileMode::Add: + case FileMode::AddFolder: + aud_drct_pl_add_list(std::move(files), -1); + break; + case FileMode::Open: + case FileMode::OpenFolder: + aud_drct_pl_open_list(std::move(files)); + break; + case FileMode::ImportPlaylist: + if (files.len() == 1) + import_playlist(playlist, files[0].filename); + break; + case FileMode::ExportPlaylist: + if (files.len() == 1) + export_playlist(playlist, files[0].filename); + break; + default: + /* not reached */ + break; + } + }); + } + + window_bring_to_front(dialog); +} + +} // namespace audqt diff --git a/src/libaudqt/font-entry.cc b/src/libaudqt/font-entry.cc new file mode 100644 index 0000000..ff5b698 --- /dev/null +++ b/src/libaudqt/font-entry.cc @@ -0,0 +1,167 @@ +/* + * font-entry.cc + * Copyright 2015 John Lindgren + * Copyright 2019 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt.h" + +#include <QAction> +#include <QFontDialog> +#include <QLineEdit> +#include <QPointer> + +#include <libaudcore/audstrings.h> +#include <libaudcore/i18n.h> + +namespace audqt +{ + +class FontEntry : public QLineEdit +{ +public: + FontEntry(QWidget * parent = nullptr, const char * font = nullptr) + : QLineEdit(parent), + m_action(get_icon("preferences-desktop-font"), _("Set Font"), nullptr) + { + addAction(&m_action, TrailingPosition); + connect(&m_action, &QAction::triggered, this, &FontEntry::show_dialog); + + if (font) + setText(font); + + end(false); + } + +private: + void show_dialog(); + + QAction m_action; + QPointer<QFontDialog> m_dialog; +}; + +/* parse a subset of Pango font descriptions */ +EXPORT QFont qfont_from_string(const char * name) +{ + auto family = str_copy(name); + int size = 0; + QFont::Weight weight = QFont::Normal; + QFont::Style style = QFont::StyleNormal; + QFont::Stretch stretch = QFont::Unstretched; + + while (1) + { + /* check for attributes */ + bool attr_found = false; + const char * space = strrchr(family, ' '); + + if (space) + { + const char * attr = space + 1; + int num = str_to_int(attr); + + attr_found = true; + + if (num > 0) + size = num; + else if (!strcmp(attr, "Light")) + weight = QFont::Light; + else if (!strcmp(attr, "Bold")) + weight = QFont::Bold; + else if (!strcmp(attr, "Oblique")) + style = QFont::StyleOblique; + else if (!strcmp(attr, "Italic")) + style = QFont::StyleItalic; + else if (!strcmp(attr, "Condensed")) + stretch = QFont::Condensed; + else if (!strcmp(attr, "Expanded")) + stretch = QFont::Expanded; + else + attr_found = false; + } + + if (!attr_found) + { + QFont font((const char *)family); + + if (size > 0) + font.setPointSize(size); + if (weight != QFont::Normal) + font.setWeight(weight); + if (style != QFont::StyleNormal) + font.setStyle(style); + if (stretch != QFont::Unstretched) + font.setStretch(stretch); + + return font; + } + + family.resize(space - family); + } +} + +EXPORT StringBuf qfont_to_string(const QFont & font) +{ + StringBuf font_str = str_copy(font.family().toUtf8()); + + auto weight = font.weight(); + auto style = font.style(); + auto stretch = font.stretch(); + + if (weight == QFont::Light) + font_str.insert(-1, " Light"); + else if (weight == QFont::Bold) + font_str.insert(-1, " Bold"); + + if (style == QFont::StyleOblique) + font_str.insert(-1, " Oblique"); + else if (style == QFont::StyleItalic) + font_str.insert(-1, " Italic"); + + if (stretch == QFont::Condensed) + font_str.insert(-1, " Condensed"); + else if (stretch == QFont::Expanded) + font_str.insert(-1, " Expanded"); + + str_append_printf(font_str, " %d", font.pointSize()); + + return font_str; +} + +void FontEntry::show_dialog() +{ + if (!m_dialog) + { + m_dialog = new QFontDialog(this); + + QObject::connect(m_dialog.data(), &QFontDialog::fontSelected, + [this](const QFont & font) { + setText((const char *)qfont_to_string(font)); + end(false); + }); + } + + m_dialog->setCurrentFont(qfont_from_string(text().toUtf8())); + window_bring_to_front(m_dialog); +} + +EXPORT QLineEdit * font_entry_new(QWidget * parent, const char * font) +{ + return new FontEntry(parent, font); +} + +} // namespace audqt diff --git a/src/libaudqt/iface.h b/src/libaudqt/iface.h new file mode 100644 index 0000000..99b0ff4 --- /dev/null +++ b/src/libaudqt/iface.h @@ -0,0 +1,63 @@ +/* + * iface.h + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDQT_IFACE_H +#define LIBAUDQT_IFACE_H + +#include <libaudcore/plugin.h> +#include <libaudqt/export.h> +#include <libaudqt/libaudqt.h> +#include <libaudqt/menu.h> + +namespace audqt +{ + +class LIBAUDQT_PUBLIC QtIfacePlugin : public IfacePlugin +{ +public: + constexpr QtIfacePlugin(PluginInfo info) : IfacePlugin(info) {} + + void show_about_window() { aboutwindow_show(); } + void hide_about_window() { aboutwindow_hide(); } + + void show_filebrowser(bool open) + { + fileopener_show(open ? FileMode::Open : FileMode::Add); + } + + void hide_filebrowser() {} + void show_jump_to_song() {} + void hide_jump_to_song() {} + void show_prefs_window() { prefswin_show(); } + void hide_prefs_window() { prefswin_hide(); } + + void plugin_menu_add(AudMenuID id, void func(), const char * name, + const char * icon) + { + menu_add(id, func, name, icon); + } + void plugin_menu_remove(AudMenuID id, void func()) + { + menu_remove(id, func); + } +}; + +} // namespace audqt + +#endif diff --git a/src/libaudqt/images.qrc b/src/libaudqt/images.qrc new file mode 100644 index 0000000..a5f18ef --- /dev/null +++ b/src/libaudqt/images.qrc @@ -0,0 +1,66 @@ +<RCC> +<qresource> + <file alias="about-logo.svg">../../images/about-logo.svg</file> + <file alias="application-exit.svg">../../images/application-exit.svg</file> + <file alias="applications-graphics.svg">../../images/applications-graphics.svg</file> + <file alias="applications-internet.svg">../../images/applications-internet.svg</file> + <file alias="applications-system.svg">../../images/applications-system.svg</file> + <file alias="appointment-new.svg">../../images/appointment-new.svg</file> + <file alias="audacious.svg">../../images/audacious.svg</file> + <file alias="audio-card.svg">../../images/audio-card.svg</file> + <file alias="audio-volume-high.svg">../../images/audio-volume-high.svg</file> + <file alias="audio-volume-low.svg">../../images/audio-volume-low.svg</file> + <file alias="audio-volume-medium.svg">../../images/audio-volume-medium.svg</file> + <file alias="audio-volume-muted.svg">../../images/audio-volume-muted.svg</file> + <file alias="audio-x-generic.svg">../../images/audio-x-generic.svg</file> + <file alias="dialog-error.svg">../../images/dialog-error.svg</file> + <file alias="dialog-information.svg">../../images/dialog-information.svg</file> + <file alias="dialog-question.svg">../../images/dialog-question.svg</file> + <file alias="dialog-warning.svg">../../images/dialog-warning.svg</file> + <file alias="document-new.svg">../../images/document-new.svg</file> + <file alias="document-open-recent.svg">../../images/document-open-recent.svg</file> + <file alias="document-open.svg">../../images/document-open.svg</file> + <file alias="document-save.svg">../../images/document-save.svg</file> + <file alias="edit-clear.svg">../../images/edit-clear.svg</file> + <file alias="edit-copy.svg">../../images/edit-copy.svg</file> + <file alias="edit-cut.svg">../../images/edit-cut.svg</file> + <file alias="edit-delete.svg">../../images/edit-delete.svg</file> + <file alias="edit-find.svg">../../images/edit-find.svg</file> + <file alias="edit-paste.svg">../../images/edit-paste.svg</file> + <file alias="edit-select-all.svg">../../images/edit-select-all.svg</file> + <file alias="face-smile.svg">../../images/face-smile.svg</file> + <file alias="folder-remote.svg">../../images/folder-remote.svg</file> + <file alias="folder.svg">../../images/folder.svg</file> + <file alias="go-down.svg">../../images/go-down.svg</file> + <file alias="go-jump.svg">../../images/go-jump.svg</file> + <file alias="go-next.svg">../../images/go-next.svg</file> + <file alias="go-previous.svg">../../images/go-previous.svg</file> + <file alias="go-up.svg">../../images/go-up.svg</file> + <file alias="help-about.svg">../../images/help-about.svg</file> + <file alias="insert-text.svg">../../images/insert-text.svg</file> + <file alias="list-add.svg">../../images/list-add.svg</file> + <file alias="list-remove.svg">../../images/list-remove.svg</file> + <file alias="media-optical.svg">../../images/media-optical.svg</file> + <file alias="media-playback-pause.svg">../../images/media-playback-pause.svg</file> + <file alias="media-playback-start.svg">../../images/media-playback-start.svg</file> + <file alias="media-playback-stop.svg">../../images/media-playback-stop.svg</file> + <file alias="media-playlist-repeat.svg">../../images/media-playlist-repeat.svg</file> + <file alias="media-playlist-shuffle.svg">../../images/media-playlist-shuffle.svg</file> + <file alias="media-record.svg">../../images/media-record.svg</file> + <file alias="media-skip-backward.svg">../../images/media-skip-backward.svg</file> + <file alias="media-skip-forward.svg">../../images/media-skip-forward.svg</file> + <file alias="multimedia-volume-control.svg">../../images/multimedia-volume-control.svg</file> + <file alias="preferences-desktop-font.svg">../../images/preferences-desktop-font.svg</file> + <file alias="preferences-system.svg">../../images/preferences-system.svg</file> + <file alias="process-stop.svg">../../images/process-stop.svg</file> + <file alias="system-run.svg">../../images/system-run.svg</file> + <file alias="text-x-generic.svg">../../images/text-x-generic.svg</file> + <file alias="user-desktop.svg">../../images/user-desktop.svg</file> + <file alias="user-home.svg">../../images/user-home.svg</file> + <file alias="user-trash.svg">../../images/user-trash.svg</file> + <file alias="view-refresh.svg">../../images/view-refresh.svg</file> + <file alias="view-sort-ascending.svg">../../images/view-sort-ascending.svg</file> + <file alias="view-sort-descending.svg">../../images/view-sort-descending.svg</file> + <file alias="window-close.svg">../../images/window-close.svg</file> +</qresource> +</RCC> diff --git a/src/libaudqt/info-widget.cc b/src/libaudqt/info-widget.cc new file mode 100644 index 0000000..b5c7408 --- /dev/null +++ b/src/libaudqt/info-widget.cc @@ -0,0 +1,425 @@ +/* + * info-widget.h + * Copyright 2006-2017 René Bertin, Thomas Lange, John Lindgren, + * Ariadne Conill, Tomasz Moń, and Eugene Zagidullin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "info-widget.h" +#include "libaudqt-internal.h" +#include "libaudqt.h" + +#include <QHeaderView> +#include <QKeyEvent> +#include <QPointer> + +#include <libaudcore/i18n.h> +#include <libaudcore/probe.h> +#include <libaudcore/runtime.h> +#include <libaudcore/tuple.h> + +namespace audqt +{ + +struct TupleFieldMap +{ + const char * name; + Tuple::Field field; + bool editable; +}; + +static const char * varied_str = N_("<various>"); + +static const TupleFieldMap tuple_field_map[] = { + {N_("Metadata"), Tuple::Invalid, false}, + {N_("Title"), Tuple::Title, true}, + {N_("Artist"), Tuple::Artist, true}, + {N_("Album"), Tuple::Album, true}, + {N_("Album Artist"), Tuple::AlbumArtist, true}, + {N_("Track Number"), Tuple::Track, true}, + {N_("Genre"), Tuple::Genre, true}, + {N_("Comment"), Tuple::Comment, true}, + {N_("Description"), Tuple::Description, true}, + {N_("Composer"), Tuple::Composer, true}, + {N_("Performer"), Tuple::Performer, true}, + {N_("Recording Year"), Tuple::Year, true}, + {N_("Recording Date"), Tuple::Date, true}, + + {nullptr, Tuple::Invalid, false}, + {N_("Technical"), Tuple::Invalid, false}, + {N_("Length"), Tuple::Length, false}, + {N_("Codec"), Tuple::Codec, false}, + {N_("Quality"), Tuple::Quality, false}, + {N_("Bitrate"), Tuple::Bitrate, false}, + {N_("MusicBrainz ID"), Tuple::MusicBrainzID, false}}; + +static const TupleFieldMap * to_field_map(const QModelIndex & index) +{ + int row = index.row(); + if (row < 0 || row >= aud::n_elems(tuple_field_map)) + return nullptr; + + return &tuple_field_map[row]; +} + +static QModelIndex sibling_field_index(const QModelIndex & current, + int direction) +{ + QModelIndex index = current; + + while (1) + { + index = index.sibling(index.row() + direction, index.column()); + auto map = to_field_map(index); + + if (!map) + return QModelIndex(); + if (map->field != Tuple::Invalid) + return index; + } +} + +static QString tuple_field_to_str(const Tuple & tuple, Tuple::Field field) +{ + switch (tuple.get_value_type(field)) + { + case Tuple::String: + return QString(tuple.get_str(field)); + case Tuple::Int: + return QString::number(tuple.get_int(field)); + default: + return QString(); + } +} + +static void tuple_field_set_from_str(Tuple & tuple, Tuple::Field field, + const QString & str) +{ + if (str.isEmpty()) + tuple.unset(field); + else if (Tuple::field_get_type(field) == Tuple::String) + tuple.set_str(field, str.toUtf8()); + else + tuple.set_int(field, str.toInt()); +} + +static bool tuple_field_is_same(const Tuple & a, const Tuple & b, + Tuple::Field field) +{ + auto a_type = a.get_value_type(field); + if (a_type != b.get_value_type(field)) + return false; + + switch (a_type) + { + case Tuple::String: + return (a.get_str(field) == b.get_str(field)); + case Tuple::Int: + return (a.get_int(field) == b.get_int(field)); + default: + return true; + } +} + +static void tuple_field_copy(Tuple & dest, const Tuple & src, + Tuple::Field field) +{ + switch (src.get_value_type(field)) + { + case Tuple::String: + dest.set_str(field, src.get_str(field)); + break; + case Tuple::Int: + dest.set_int(field, src.get_int(field)); + break; + default: + dest.unset(field); + break; + } +} + +class InfoModel : public QAbstractTableModel +{ +public: + enum + { + Col_Name = 0, + Col_Value = 1 + }; + + InfoModel(QObject * parent = nullptr) : QAbstractTableModel(parent) {} + + int rowCount(const QModelIndex & parent) const override + { + return parent.isValid() ? 0 : aud::n_elems(tuple_field_map); + } + + int columnCount(const QModelIndex &) const override { return 2; } + + QVariant data(const QModelIndex & index, int role) const override; + bool setData(const QModelIndex & index, const QVariant & value, + int role) override; + Qt::ItemFlags flags(const QModelIndex & index) const override; + + void setItems(Index<PlaylistAddItem> && items) + { + m_items = std::move(items); + revertTupleData(); + } + + void linkEnabled(QWidget * widget) + { + widget->setEnabled(m_changed_mask != 0); + m_linked_widgets.append(widget); + } + + void revertTupleData(); + bool updateFile() const; + +private: + void updateEnabled() + { + for (auto & widget : m_linked_widgets) + { + if (widget) + widget->setEnabled(m_changed_mask != 0); + } + } + + /* set of filenames, original tuples, decoders */ + Index<PlaylistAddItem> m_items; + /* local (possibly edited) tuple */ + Tuple m_tuple; + /* bitmask of fields which vary between tuples and will be preserved */ + uint64_t m_varied_mask = 0; + /* bitmask of fields which have been edited */ + uint64_t m_changed_mask = 0; + /* list of widgets to enable when edits have been made */ + QList<QPointer<QWidget>> m_linked_widgets; +}; + +EXPORT InfoWidget::InfoWidget(QWidget * parent) + : QTreeView(parent), m_model(new InfoModel(this)) +{ + setModel(m_model); + header()->hide(); + setIndentation(0); + resizeColumnToContents(0); + setContextMenuPolicy(Qt::CustomContextMenu); + + connect(this, &QWidget::customContextMenuRequested, + [this](const QPoint & pos) { + auto index = indexAt(pos); + if (index.column() != InfoModel::Col_Value) + return; + auto text = m_model->data(index, Qt::DisplayRole).toString(); + if (!text.isEmpty()) + show_copy_context_menu(this, mapToGlobal(pos), text); + }); +} + +EXPORT InfoWidget::~InfoWidget() {} + +EXPORT void InfoWidget::fillInfo(const char * filename, const Tuple & tuple, + PluginHandle * decoder, bool updating_enabled) +{ + Index<PlaylistAddItem> items; + items.append(String(filename), tuple.ref(), decoder); + fillInfo(std::move(items), updating_enabled); +} + +EXPORT void InfoWidget::fillInfo(Index<PlaylistAddItem> && items, + bool updating_enabled) +{ + m_model->setItems(std::move(items)); + reset(); + + setEditTriggers(updating_enabled ? QAbstractItemView::AllEditTriggers + : QAbstractItemView::NoEditTriggers); + + auto initial_index = m_model->index(1 /* title */, InfoModel::Col_Value); + setCurrentIndex(initial_index); +} + +EXPORT void InfoWidget::linkEnabled(QWidget * widget) +{ + m_model->linkEnabled(widget); +} + +EXPORT void InfoWidget::revertInfo() +{ + m_model->revertTupleData(); + reset(); +} + +EXPORT bool InfoWidget::updateFile() { return m_model->updateFile(); } + +void InfoWidget::keyPressEvent(QKeyEvent * event) +{ + if (event->type() == QEvent::KeyPress && + (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down)) + { + auto index = sibling_field_index(currentIndex(), + (event->key() == Qt::Key_Up) ? -1 : 1); + if (index.isValid()) + setCurrentIndex(index); + + event->accept(); + return; + } + + QTreeView::keyPressEvent(event); +} + +void InfoModel::revertTupleData() +{ + m_tuple = (m_items.len() > 0) ? m_items[0].tuple.ref() : Tuple(); + m_varied_mask = 0; + m_changed_mask = 0; + + for (auto & item : m_items) + { + for (auto field : Tuple::all_fields()) + { + if (!tuple_field_is_same(item.tuple, m_tuple, field)) + m_varied_mask |= (uint64_t)1 << (int)field; + } + } + + updateEnabled(); +} + +bool InfoModel::updateFile() const +{ + if (m_changed_mask == 0) + return true; + + int n_saved = 0; + + for (auto & item : m_items) + { + auto new_tuple = item.tuple.ref(); + + for (auto field : Tuple::all_fields()) + { + uint64_t mask = ((uint64_t)1 << (int)field); + if ((m_changed_mask & mask) != 0) + tuple_field_copy(new_tuple, m_tuple, field); + } + + if (aud_file_write_tuple(item.filename, item.decoder, new_tuple)) + n_saved++; + } + + return (n_saved == m_items.len()); +} + +bool InfoModel::setData(const QModelIndex & index, const QVariant & value, + int role) +{ + if (role != Qt::EditRole) + return false; + + auto map = to_field_map(index); + if (!map || map->field == Tuple::Invalid) + return false; + + uint64_t mask = ((uint64_t)1 << (int)map->field); + auto str = value.toString(); + + /* prevent accidental overwrite of varied values */ + if ((m_varied_mask & mask) != 0 && str == _(varied_str)) + return false; + + if ((m_varied_mask & mask) != 0 || + str != tuple_field_to_str(m_tuple, map->field)) + { + tuple_field_set_from_str(m_tuple, map->field, str); + m_varied_mask &= ~mask; + m_changed_mask |= mask; + updateEnabled(); + } + + emit dataChanged(index, index, {role}); + return true; +} + +QVariant InfoModel::data(const QModelIndex & index, int role) const +{ + auto map = to_field_map(index); + if (!map) + return QVariant(); + + uint64_t mask = 0; + if (map->field != Tuple::Invalid) + mask = ((uint64_t)1 << (int)map->field); + + if (role == Qt::DisplayRole || role == Qt::EditRole) + { + if (index.column() == InfoModel::Col_Name) + return translate_str(map->name); + else if (index.column() == InfoModel::Col_Value) + { + if (map->field == Tuple::Invalid) + return QVariant(); + + if ((m_varied_mask & mask) != 0) + return QString(_(varied_str)); + + return tuple_field_to_str(m_tuple, map->field); + } + } + else if (role == Qt::FontRole) + { + if ((index.column() == Col_Name && map->field == Tuple::Invalid) || + (index.column() == Col_Value && (m_changed_mask & mask) != 0)) + { + QFont f; + f.setBold(true); + return f; + } + else if (index.column() == Col_Value && (m_varied_mask & mask) != 0) + { + QFont f; + f.setItalic(true); + return f; + } + + return QVariant(); + } + + return QVariant(); +} + +Qt::ItemFlags InfoModel::flags(const QModelIndex & index) const +{ + if (index.column() == InfoModel::Col_Value) + { + auto map = to_field_map(index); + + if (!map || map->field == Tuple::Invalid) + return Qt::ItemNeverHasChildren; + else if (map->editable) + return Qt::ItemIsSelectable | Qt::ItemIsEditable | + Qt::ItemIsEnabled; + + return Qt::ItemIsEnabled; + } + + return Qt::ItemNeverHasChildren; +} + +} // namespace audqt diff --git a/src/libaudqt/info-widget.h b/src/libaudqt/info-widget.h new file mode 100644 index 0000000..40f3d2d --- /dev/null +++ b/src/libaudqt/info-widget.h @@ -0,0 +1,59 @@ +/* + * info-widget.h + * Copyright 2006-2014 Ariadne Conill, Tomasz Moń, Eugene Zagidullin, + * John Lindgren, and Thomas Lange + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDQT_INFO_WIDGET_H +#define LIBAUDQT_INFO_WIDGET_H + +#include <QTreeView> +#include <libaudcore/index.h> +#include <libaudqt/export.h> + +struct PlaylistAddItem; +class PluginHandle; +class Tuple; + +namespace audqt +{ + +class InfoModel; + +class LIBAUDQT_PUBLIC InfoWidget : public QTreeView +{ +public: + InfoWidget(QWidget * parent = nullptr); + ~InfoWidget(); + + void fillInfo(const char * filename, const Tuple & tuple, + PluginHandle * decoder, bool updating_enabled); + void fillInfo(Index<PlaylistAddItem> && items, bool updating_enabled); + void linkEnabled(QWidget * widget); + void revertInfo(); + bool updateFile(); + +protected: + void keyPressEvent(QKeyEvent * event) override; + +private: + InfoModel * m_model; +}; + +} // namespace audqt + +#endif // LIBAUDQT_INFO_WIDGET_H diff --git a/src/libaudqt/infopopup-qt.cc b/src/libaudqt/infopopup-qt.cc new file mode 100644 index 0000000..a8c6f7a --- /dev/null +++ b/src/libaudqt/infopopup-qt.cc @@ -0,0 +1,202 @@ +/* + * infopopup-qt.cc + * Copyright 2018 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <libaudcore/audstrings.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/playlist.h> +#include <libaudcore/tuple.h> + +#include "libaudqt-internal.h" +#include "libaudqt.h" + +#include <QBoxLayout> +#include <QGridLayout> +#include <QLabel> +#include <QPainter> +#include <QPointer> + +namespace audqt +{ + +class InfoPopup : public PopupWidget +{ +public: + InfoPopup(const String & filename, const Tuple & tuple); + +private: + void add_field(int row, const char * field, const char * value); + void add_fields(const Tuple & tuple); + void art_ready(const char * filename); + void finish_loading(); + + void paintEvent(QPaintEvent *) override; + + HookReceiver<InfoPopup, const char *> art_ready_hook{"art ready", this, + &InfoPopup::art_ready}; + + const String m_filename; + const QGradientStops m_stops; + + QHBoxLayout m_hbox; + QGridLayout m_grid; + bool m_queued = false; +}; + +InfoPopup::InfoPopup(const String & filename, const Tuple & tuple) + : m_filename(filename), + m_stops(dark_bg_gradient(palette().color(QPalette::Window))) +{ + setWindowFlags(Qt::ToolTip); + + m_hbox.setMargin(sizes.TwoPt); + m_hbox.setSpacing(sizes.FourPt); + setLayout(&m_hbox); + + m_grid.setMargin(0); + m_grid.setHorizontalSpacing(sizes.FourPt); + m_grid.setVerticalSpacing(0); + m_hbox.addLayout(&m_grid); + + add_fields(tuple); + finish_loading(); +} + +void InfoPopup::add_fields(const Tuple & tuple) +{ + String title = tuple.get_str(Tuple::Title); + String artist = tuple.get_str(Tuple::Artist); + String album = tuple.get_str(Tuple::Album); + String genre = tuple.get_str(Tuple::Genre); + + int year = tuple.get_int(Tuple::Year); + int track = tuple.get_int(Tuple::Track); + int length = tuple.get_int(Tuple::Length); + int row = 0; + + if (title) + add_field(row++, _("Title"), title); + if (artist) + add_field(row++, _("Artist"), artist); + if (album) + add_field(row++, _("Album"), album); + if (genre) + add_field(row++, _("Genre"), genre); + if (year > 0) + add_field(row++, _("Year"), int_to_str(year)); + if (track > 0) + add_field(row++, _("Track"), int_to_str(track)); + if (length > 0) + add_field(row++, _("Length"), str_format_time(length)); + + if (row > 0) + m_grid.setRowStretch(row - 1, 1); +} + +void InfoPopup::add_field(int row, const char * field, const char * value) +{ + auto header = new QLabel(this); + header->setTextFormat(Qt::RichText); + header->setText( + QString("<i><font color=\"#a0a0a0\">%1</font></i>").arg(field)); + m_grid.addWidget(header, row, 0, Qt::AlignRight | Qt::AlignTop); + + auto label = new QLabel(this); + header->setTextFormat(Qt::RichText); + auto html = QString(value).toHtmlEscaped(); + label->setText(QString("<font color=\"#ffffff\">%1</font>").arg(html)); + m_grid.addWidget(label, row, 1, Qt::AlignLeft | Qt::AlignTop); +} + +void InfoPopup::art_ready(const char * filename) +{ + if (m_queued && strcmp(filename, m_filename) == 0) + finish_loading(); +} + +void InfoPopup::finish_loading() +{ + QImage image = art_request(m_filename, &m_queued); + + if (!image.isNull()) + { + auto label = new QLabel(this); + label->setPixmap(art_scale(image, sizes.OneInch, sizes.OneInch)); + m_hbox.insertWidget(0, label); + } + + if (!m_queued) + show(); +} + +void InfoPopup::paintEvent(QPaintEvent *) +{ + QLinearGradient grad(0, 0, 0, height()); + grad.setStops(m_stops); + + QPainter p(this); + p.fillRect(rect(), grad); +} + +static QPointer<InfoPopup> s_infopopup; + +static void infopopup_show(const String & filename, const Tuple & tuple) +{ + if (s_infopopup) + s_infopopup->deleteLater(); + + s_infopopup = new InfoPopup(filename, tuple); +} + +EXPORT void infopopup_show(Playlist playlist, int entry) +{ + String filename = playlist.entry_filename(entry); + Tuple tuple = playlist.entry_tuple(entry); + + if (filename && tuple.valid()) + infopopup_show(filename, tuple); +} + +EXPORT void infopopup_show_current() +{ + auto playlist = Playlist::playing_playlist(); + if (playlist == Playlist()) + playlist = Playlist::active_playlist(); + + int position = playlist.get_position(); + if (position >= 0) + infopopup_show(playlist, position); +} + +EXPORT void infopopup_hide() +{ + /* This function can be called from an enter/leave event, and Qt does not + * like widgets being deleted from such events. This is debatably a bug in + * Qt, but deleteLater() is an effective workaround. */ + if (s_infopopup) + s_infopopup->deleteLater(); +} + +void infopopup_hide_now() +{ + /* On exit, we really do want to delete the widget immediately. */ + delete s_infopopup; +} + +} // namespace audqt diff --git a/src/libaudqt/infowin-qt.cc b/src/libaudqt/infowin-qt.cc new file mode 100644 index 0000000..02781f9 --- /dev/null +++ b/src/libaudqt/infowin-qt.cc @@ -0,0 +1,297 @@ +/* + * infowin.cc + * Copyright 2006-2014 Ariadne Conill, Tomasz Moń, Eugene Zagidullin, + * John Lindgren, and Thomas Lange + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <math.h> + +#include <QDialog> +#include <QDialogButtonBox> +#include <QEvent> +#include <QHBoxLayout> +#include <QImage> +#include <QLabel> +#include <QPainter> +#include <QPixmap> +#include <QPointer> +#include <QPushButton> +#include <QTextDocument> +#include <QVBoxLayout> + +#include <libaudcore/audstrings.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/interface.h> +#include <libaudcore/playlist.h> +#include <libaudcore/probe.h> + +#include "info-widget.h" +#include "libaudqt-internal.h" +#include "libaudqt.h" + +namespace audqt +{ + +/* This class remedies some of the deficiencies of QLabel (such as lack + * of proper wrapping). It can be expanded and/or made more visible if + * it turns out to be useful outside InfoWindow. */ +class TextWidget : public QWidget +{ +public: + TextWidget() { m_doc.setDefaultFont(font()); } + + void setText(const QString & text) + { + m_doc.setPlainText(text); + updateGeometry(); + } + + void setWidth(int width) + { + m_doc.setTextWidth(width); + updateGeometry(); + } + +protected: + QSize sizeHint() const override + { + qreal width = m_doc.idealWidth(); + qreal height = m_doc.size().height(); + return QSize(ceil(width), ceil(height)); + } + + QSize minimumSizeHint() const override { return sizeHint(); } + + void changeEvent(QEvent * event) override + { + if (event->type() == QEvent::FontChange) + { + m_doc.setDefaultFont(font()); + updateGeometry(); + } + } + + void paintEvent(QPaintEvent * event) override + { + QPainter painter(this); + m_doc.drawContents(&painter); + } + +private: + QTextDocument m_doc; +}; + +class InfoWindow : public QDialog +{ +public: + InfoWindow(QWidget * parent = nullptr); + + void fillInfo(Index<PlaylistAddItem> && items, bool updating_enabled); + +private: + String m_filename; + QLabel m_image; + TextWidget m_uri_label; + InfoWidget m_infowidget; + QPushButton * m_save_btn; + + void displayImage(const char * filename); + + const HookReceiver<InfoWindow, const char *> art_hook{ + "art ready", this, &InfoWindow::displayImage}; +}; + +InfoWindow::InfoWindow(QWidget * parent) : QDialog(parent) +{ + setWindowTitle(_("Song Info")); + setContentsMargins(margins.TwoPt); + + m_image.setAlignment(Qt::AlignCenter); + m_uri_label.setWidth(2 * audqt::sizes.OneInch); + m_uri_label.setContextMenuPolicy(Qt::CustomContextMenu); + + connect(&m_uri_label, &QWidget::customContextMenuRequested, + [this](const QPoint & pos) { + show_copy_context_menu(this, m_uri_label.mapToGlobal(pos), + QString(m_filename)); + }); + + auto left_vbox = make_vbox(nullptr); + left_vbox->addWidget(&m_image); + left_vbox->addWidget(&m_uri_label); + left_vbox->setStretch(0, 1); + left_vbox->setStretch(1, 0); + + auto hbox = make_hbox(nullptr); + hbox->addLayout(left_vbox); + hbox->addWidget(&m_infowidget); + + auto vbox = make_vbox(this); + vbox->addLayout(hbox); + + auto bbox = + new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Close | + QDialogButtonBox::Reset, + this); + + m_save_btn = bbox->button(QDialogButtonBox::Save); + auto close_btn = bbox->button(QDialogButtonBox::Close), + revert_btn = bbox->button(QDialogButtonBox::Reset); + + close_btn->setText(translate_str(N_("_Close"))); + revert_btn->setText(translate_str(N_("_Revert"))); + + m_infowidget.linkEnabled(m_save_btn); + m_infowidget.linkEnabled(revert_btn); + + vbox->addWidget(bbox); + + connect(bbox, &QDialogButtonBox::accepted, [this]() { + if (m_infowidget.updateFile()) + deleteLater(); + else + aud_ui_show_error(str_printf(_("Error writing tag(s)."))); + }); + + connect(bbox, &QDialogButtonBox::rejected, this, &QObject::deleteLater); + connect(revert_btn, &QPushButton::clicked, &m_infowidget, + &InfoWidget::revertInfo); +} + +void InfoWindow::fillInfo(Index<PlaylistAddItem> && items, + bool updating_enabled) +{ + if (items.len() == 1) + { + m_filename = String(items[0].filename); + m_uri_label.setText((QString)uri_to_display(m_filename)); + displayImage(m_filename); + m_save_btn->setText(translate_str(N_("_Save"))); + } + else + { + m_filename = String(); + m_uri_label.setText( + translate_str(N_("%1 files selected")).arg(items.len())); + m_image.setPixmap( + get_icon("audio-x-generic").pixmap(to_native_dpi(48))); + m_save_btn->setText( + translate_str(N_("_Save %1 files")).arg(items.len())); + } + + m_infowidget.fillInfo(std::move(items), updating_enabled); +} + +void InfoWindow::displayImage(const char * filename) +{ + if (!strcmp_safe(filename, m_filename)) + m_image.setPixmap( + art_request(filename, 2 * sizes.OneInch, 2 * sizes.OneInch)); +} + +static QPointer<InfoWindow> s_infowin; + +static void show_infowin(Index<PlaylistAddItem> && items, bool can_write) +{ + if (!s_infowin) + { + s_infowin = new InfoWindow; + s_infowin->setAttribute(Qt::WA_DeleteOnClose); + } + + s_infowin->fillInfo(std::move(items), can_write); + s_infowin->resize(6 * sizes.OneInch, 3 * sizes.OneInch); + window_bring_to_front(s_infowin); +} + +static void fetch_entry(Playlist playlist, int entry, + Index<PlaylistAddItem> & items, bool & can_write) +{ + String filename = playlist.entry_filename(entry); + if (!filename) + return; + + String error; + PluginHandle * decoder = + playlist.entry_decoder(entry, Playlist::Wait, &error); + Tuple tuple = + decoder ? playlist.entry_tuple(entry, Playlist::Wait, &error) : Tuple(); + + if (decoder && tuple.valid()) + { + /* cuesheet entries cannot be updated */ + can_write = (can_write && aud_file_can_write_tuple(filename, decoder) && + !tuple.is_set(Tuple::StartTime)); + + tuple.delete_fallbacks(); + items.append(filename, std::move(tuple), decoder); + } + + if (error) + aud_ui_show_error(str_printf(_("Error opening %s:\n%s"), + (const char *)filename, + (const char *)error)); +} + +EXPORT void infowin_show(Playlist playlist, int entry) +{ + Index<PlaylistAddItem> items; + bool can_write = true; + + fetch_entry(playlist, entry, items, can_write); + + if (items.len()) + show_infowin(std::move(items), can_write); + else + infowin_hide(); +} + +EXPORT void infowin_show_selected(Playlist playlist) +{ + Index<PlaylistAddItem> items; + bool can_write = true; + + int n_entries = playlist.n_entries(); + for (int entry = 0; entry < n_entries; entry++) + { + if (playlist.entry_selected(entry)) + fetch_entry(playlist, entry, items, can_write); + } + + if (items.len()) + show_infowin(std::move(items), can_write); + else + infowin_hide(); +} + +EXPORT void infowin_show_current() +{ + auto playlist = Playlist::playing_playlist(); + if (playlist == Playlist()) + playlist = Playlist::active_playlist(); + + int position = playlist.get_position(); + if (position < 0) + return; + + infowin_show(playlist, position); +} + +EXPORT void infowin_hide() { delete s_infowin; } + +} // namespace audqt diff --git a/src/libaudqt/libaudqt-internal.h b/src/libaudqt/libaudqt-internal.h new file mode 100644 index 0000000..3d67a45 --- /dev/null +++ b/src/libaudqt/libaudqt-internal.h @@ -0,0 +1,58 @@ +/* + * libaudqt-internal.h + * Copyright 2016-2017 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDQT_INTERNAL_H +#define LIBAUDQT_INTERNAL_H + +#include <QWidget> + +class QPoint; +class QScreen; +class QString; + +namespace audqt +{ + +/* infopopup.cc */ +void infopopup_hide_now(); + +/* log-inspector.cc */ +void log_init(); +void log_cleanup(); + +/* prefs-plugin.cc */ +void plugin_prefs_hide(); + +/* util-qt.cc */ +class PopupWidget : public QWidget +{ +public: + PopupWidget(QWidget * parent = nullptr); + +protected: + bool eventFilter(QObject *, QEvent * e) override; + void showEvent(QShowEvent *) override; +}; + +void show_copy_context_menu(QWidget * parent, const QPoint & global_pos, + const QString & text_to_copy); + +} // namespace audqt + +#endif // LIBAUDQT_INTERNAL_H diff --git a/src/libaudqt/libaudqt.h b/src/libaudqt/libaudqt.h new file mode 100644 index 0000000..54f902d --- /dev/null +++ b/src/libaudqt/libaudqt.h @@ -0,0 +1,197 @@ +/* + * libaudqt.h + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDQT_H +#define LIBAUDQT_H + +#include <QFileDialog> +#include <QMargins> +#include <QMessageBox> +#include <QString> +#include <libaudcore/objects.h> + +class QBoxLayout; +class QHBoxLayout; +class QIcon; +class QLayout; +class QLineEdit; +class QPixmap; +class QToolButton; +class QVBoxLayout; +class QWidget; + +enum class PluginType; +class Playlist; +class PluginHandle; +struct PreferencesWidget; + +namespace audqt +{ + +enum class FileMode +{ + Open, + OpenFolder, + Add, + AddFolder, + ImportPlaylist, + ExportPlaylist, + count +}; + +struct PixelSizes +{ + int OneInch; + int TwoPt; + int FourPt; + int EightPt; +}; + +struct PixelMargins +{ + QMargins TwoPt; + QMargins FourPt; + QMargins EightPt; +}; + +struct MenuItem; + +/* about.cc */ +void aboutwindow_show(); +void aboutwindow_hide(); + +/* playlist-management.cc */ +void playlist_show_rename(Playlist playlist); +void playlist_confirm_delete(Playlist playlist); + +/* equalizer.cc */ +void equalizer_show(); +void equalizer_hide(); + +/* eq-preset-qt.cc */ +void eq_presets_show(); +void eq_presets_hide(); + +/* fileopener.cc */ +void fileopener_show(FileMode mode); + +/* url-opener.cc */ +void urlopener_show(bool open); + +/* audqt.cc */ +extern const PixelSizes & sizes; +extern const PixelMargins & margins; + +static inline int to_native_dpi(int x) +{ + return aud::rescale(x, 96, sizes.OneInch); +} +static inline int to_portable_dpi(int x) +{ + return aud::rescale(x, sizes.OneInch, 96); +} + +void init(); +void run(); +void quit(); +void cleanup(); + +QIcon get_icon(const char * name); + +QGradientStops dark_bg_gradient(const QColor & base); +QColor vis_bar_color(const QColor & hue, int bar, int n_bars); + +QHBoxLayout * make_hbox(QWidget * parent, int spacing = sizes.FourPt); +QVBoxLayout * make_vbox(QWidget * parent, int spacing = sizes.FourPt); + +void enable_layout(QLayout * layout, bool enabled); +void clear_layout(QLayout * layout); +void window_bring_to_front(QWidget * win); +void simple_message(const char * title, const char * text); +void simple_message(const char * title, const char * text, + QMessageBox::Icon icon); +QString translate_str(const char * str, const char * domain); + +#ifdef PACKAGE +static inline QString translate_str(const char * str) +{ + return translate_str(str, PACKAGE); +} +#endif + +/* file-entry.cc */ +QLineEdit * file_entry_new(QWidget * parent, const char * title, + QFileDialog::FileMode file_mode, + QFileDialog::AcceptMode accept_mode); +String file_entry_get_uri(QLineEdit * entry); +void file_entry_set_uri(QLineEdit * entry, const char * uri); + +/* font-entry.cc */ +QLineEdit * font_entry_new(QWidget * parent, const char * font); +QFont qfont_from_string(const char * name); +StringBuf qfont_to_string(const QFont & font); + +/* prefs-builder.cc */ +void prefs_populate(QBoxLayout * layout, ArrayRef<PreferencesWidget> widgets, + const char * domain); + +/* prefs-plugin.cc */ +void plugin_about(PluginHandle * ph); +void plugin_prefs(PluginHandle * ph); + +/* prefs-window.cc */ +void prefswin_show(); +void prefswin_hide(); +void prefswin_show_page(int id, bool show = true); +void prefswin_show_plugin_page(PluginType type); + +/* log-inspector.cc */ +void log_inspector_show(); +void log_inspector_hide(); + +/* art-qt.cc */ +QImage art_request(const char * filename, bool * queued = nullptr); +QPixmap art_scale(const QImage & image, unsigned int w, unsigned int h, + bool want_hidpi = true); +QPixmap art_request(const char * filename, unsigned int w, unsigned int h, + bool want_hidpi = true); +QPixmap art_request_current(unsigned int w, unsigned int h, + bool want_hidpi = true); + +/* infopopup-qt.cc */ +void infopopup_show(Playlist playlist, int entry); +void infopopup_show_current(); +void infopopup_hide(); + +/* infowin.cc */ +void infowin_show(Playlist playlist, int entry); +void infowin_show_selected(Playlist playlist); +void infowin_show_current(); +void infowin_hide(); + +/* queue-manager.cc */ +void queue_manager_show(); +void queue_manager_hide(); + +/* volumebutton.cc */ +QToolButton * volume_button_new(QWidget * parent = nullptr); + +} // namespace audqt + +#endif diff --git a/src/libaudqt/log-inspector.cc b/src/libaudqt/log-inspector.cc new file mode 100644 index 0000000..028f757 --- /dev/null +++ b/src/libaudqt/log-inspector.cc @@ -0,0 +1,285 @@ +/* + * log-inspector.cc + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt-internal.h" +#include "libaudqt.h" + +#include <QComboBox> +#include <QDialog> +#include <QDialogButtonBox> +#include <QHBoxLayout> +#include <QLabel> +#include <QPointer> +#include <QPushButton> +#include <QTreeView> +#include <QVBoxLayout> +#include <QWidget> + +#include <libaudcore/audstrings.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/ringbuf.h> +#include <libaudcore/runtime.h> + +#define LOGENTRY_MAX 1024 + +namespace audqt +{ + +enum LogEntryColumn +{ + Level, + Function, + Message, + Count +}; + +struct LogEntry +{ + audlog::Level level; + String function; + String message; +}; + +class LogEntryModel : public QAbstractListModel +{ +public: + LogEntryModel(QObject * parent = nullptr) : QAbstractListModel(parent) {} + + void cleanup(); + +protected: + int rowCount(const QModelIndex & parent = QModelIndex()) const + { + return parent.isValid() ? 0 : m_entries.len(); + } + + int columnCount(const QModelIndex & parent = QModelIndex()) const + { + return LogEntryColumn::Count; + } + + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + +private: + RingBuf<LogEntry> m_entries; + + void addEntry(const LogEntry * entry); + HookReceiver<LogEntryModel, const LogEntry *> log_hook{ + "audqt log entry", this, &LogEntryModel::addEntry}; +}; + +void LogEntryModel::cleanup() +{ + if (m_entries.len() > 0) + { + beginRemoveRows(QModelIndex(), 0, m_entries.len() - 1); + m_entries.destroy(); + endRemoveRows(); + } +} + +/* log entry model */ +void LogEntryModel::addEntry(const LogEntry * entry) +{ + if (!m_entries.space()) + { + if (m_entries.len() < LOGENTRY_MAX) + m_entries.alloc(aud::max(16, 2 * m_entries.len())); + else + { + beginRemoveRows(QModelIndex(), 0, 0); + m_entries.pop(); + endRemoveRows(); + } + } + + beginInsertRows(QModelIndex(), m_entries.len(), m_entries.len()); + m_entries.push(*entry); + endInsertRows(); +} + +QVariant LogEntryModel::data(const QModelIndex & index, int role) const +{ + int row = index.row(); + if (row < 0 || row >= m_entries.len()) + return QVariant(); + + auto & e = m_entries[row]; + + if (role == Qt::DisplayRole) + { + switch (index.column()) + { + case LogEntryColumn::Level: + return QString(audlog::get_level_name(e.level)); + case LogEntryColumn::Function: + return QString(e.function); + case LogEntryColumn::Message: + return QString(e.message); + } + } + + return QVariant(); +} + +QVariant LogEntryModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (role == Qt::DisplayRole && orientation == Qt::Horizontal) + { + switch (section) + { + case LogEntryColumn::Level: + return QString(_("Level")); + case LogEntryColumn::Function: + return QString(_("Function")); + case LogEntryColumn::Message: + return QString(_("Message")); + } + } + + return QVariant(); +} + +/* static model */ +static SmartPtr<LogEntryModel> s_model; +static audlog::Level s_level = audlog::Warning; + +static void log_handler(audlog::Level level, const char * file, int line, + const char * func, const char * message) +{ + auto messages = str_list_to_index(message, "\n"); + + for (auto & message : messages) + { + auto entry = new LogEntry; + + entry->level = level; + entry->function = String(str_printf("%s (%s:%d)", func, file, line)); + entry->message = std::move(message); + + event_queue("audqt log entry", entry, aud::delete_obj<LogEntry>); + } +} + +void log_init() +{ + s_model.capture(new LogEntryModel); + audlog::subscribe(log_handler, s_level); +} + +void log_cleanup() +{ + audlog::unsubscribe(log_handler); + event_queue_cancel("audqt log entry"); + s_model.clear(); +} + +/* log entry inspector */ +class LogEntryInspector : public QDialog +{ +public: + LogEntryInspector(QWidget * parent = nullptr); + +private: + QComboBox m_level_combobox; + + void setLogLevel(audlog::Level level); +}; + +LogEntryInspector::LogEntryInspector(QWidget * parent) : QDialog(parent) +{ + setWindowTitle(_("Log Inspector")); + setContentsMargins(margins.TwoPt); + + auto view = new QTreeView(this); + view->setModel(s_model.get()); + + view->setAllColumnsShowFocus(true); + view->setIndentation(0); + view->setUniformRowHeights(true); + view->scrollToBottom(); + + m_level_combobox.addItem(_("Debug"), audlog::Debug); + m_level_combobox.addItem(_("Info"), audlog::Info); + m_level_combobox.addItem(_("Warning"), audlog::Warning); + m_level_combobox.addItem(_("Error"), audlog::Error); + + m_level_combobox.setCurrentIndex(s_level); + + QObject::connect( + &m_level_combobox, + static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + [this](int idx) { setLogLevel((audlog::Level)idx); }); + + auto btnbox = new QDialogButtonBox(this); + + auto btn1 = btnbox->addButton(translate_str(N_("Cl_ear")), + QDialogButtonBox::ActionRole); + btn1->setIcon(audqt::get_icon("edit-clear-all")); + btn1->setAutoDefault(false); + QObject::connect(btn1, &QPushButton::clicked, + []() { s_model.get()->cleanup(); }); + + auto btn2 = btnbox->addButton(QDialogButtonBox::Close); + btn2->setText(translate_str(N_("_Close"))); + btn2->setAutoDefault(false); + QObject::connect(btn2, &QPushButton::clicked, this, &QDialog::close); + + auto hbox = make_hbox(nullptr); + hbox->addWidget(new QLabel(_("Log Level:"), this)); + hbox->addWidget(&m_level_combobox); + hbox->addWidget(btnbox); + + auto vbox = make_vbox(this); + vbox->addWidget(view); + vbox->addLayout(hbox); + + resize(6 * sizes.OneInch, 3 * sizes.OneInch); +} + +static QPointer<LogEntryInspector> s_inspector; + +void LogEntryInspector::setLogLevel(audlog::Level level) +{ + s_level = level; + + audlog::unsubscribe(log_handler); + audlog::subscribe(log_handler, level); + + m_level_combobox.setCurrentIndex(level); +} + +EXPORT void log_inspector_show() +{ + if (!s_inspector) + { + s_inspector = new LogEntryInspector; + s_inspector->setAttribute(Qt::WA_DeleteOnClose); + } + + window_bring_to_front(s_inspector); +} + +EXPORT void log_inspector_hide() { delete s_inspector; } + +} // namespace audqt diff --git a/src/libaudqt/menu-qt.cc b/src/libaudqt/menu-qt.cc new file mode 100644 index 0000000..ca08ece --- /dev/null +++ b/src/libaudqt/menu-qt.cc @@ -0,0 +1,138 @@ +/* + * menu.h + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt.h" +#include "libaudqt/menu.h" + +#include <QAction> +#include <QIcon> +#include <QMenu> +#include <QMenuBar> + +#include <libaudcore/hook.h> +#include <libaudcore/runtime.h> + +namespace audqt +{ + +class MenuAction : public QAction +{ +public: + MenuAction(const MenuItem & item, const char * domain, QWidget * parent); + +private: + void toggle(bool checked); + void update(); + + const MenuItem & m_item; + SmartPtr<HookReceiver<MenuAction>> m_hook; +}; + +MenuAction::MenuAction(const MenuItem & item, const char * domain, + QWidget * parent) + : QAction(parent), m_item(item) +{ + if (item.sep) + { + setSeparator(true); + return; + } + + setText(translate_str(item.text.name, domain)); + + if (item.cfg.name) + { + setCheckable(true); + setChecked(aud_get_bool(item.cfg.sect, item.cfg.name)); + + QObject::connect(this, &QAction::toggled, this, &MenuAction::toggle); + + if (item.cfg.hook) + m_hook.capture(new HookReceiver<MenuAction>(item.cfg.hook, this, + &MenuAction::update)); + } + else if (item.func) + QObject::connect(this, &QAction::triggered, item.func); + else if (item.items.len) + setMenu(menu_build(item.items, domain, parent)); + else if (item.submenu) + setMenu(item.submenu()); + +#ifndef Q_OS_MAC + if (item.text.icon && QIcon::hasThemeIcon(item.text.icon)) + setIcon(audqt::get_icon(item.text.icon)); +#endif + + if (item.text.shortcut) + setShortcut(QString(item.text.shortcut)); + + if (parent) + parent->addAction(this); +} + +void MenuAction::toggle(bool checked) +{ + if (aud_get_bool(m_item.cfg.sect, m_item.cfg.name) != checked) + { + aud_set_bool(m_item.cfg.sect, m_item.cfg.name, checked); + + if (m_item.func) + m_item.func(); + } +} + +void MenuAction::update() +{ + setChecked(aud_get_bool(m_item.cfg.sect, m_item.cfg.name)); +} + +EXPORT QAction * menu_action(const MenuItem & menu_item, const char * domain, + QWidget * parent) +{ + return new MenuAction(menu_item, domain, parent); +} + +EXPORT QMenu * menu_build(ArrayRef<MenuItem> menu_items, const char * domain, + QWidget * parent) +{ + QMenu * m = new QMenu(parent); + + for (auto & it : menu_items) + m->addAction(new MenuAction(it, domain, parent)); + + return m; +} + +EXPORT QMenuBar * menubar_build(ArrayRef<MenuItem> menu_items, + const char * domain, QWidget * parent) +{ +#ifdef Q_OS_MAC + QMenuBar * m = new QMenuBar(nullptr); +#else + QMenuBar * m = new QMenuBar(parent); + m->setContextMenuPolicy(Qt::PreventContextMenu); +#endif + + for (auto & it : menu_items) + m->addAction(new MenuAction(it, domain, parent)); + + return m; +} + +} // namespace audqt diff --git a/src/libaudqt/menu.h b/src/libaudqt/menu.h new file mode 100644 index 0000000..b93daa3 --- /dev/null +++ b/src/libaudqt/menu.h @@ -0,0 +1,122 @@ +/* + * menu.h + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt.h" + +#ifndef LIBAUDQT_MENU_H +#define LIBAUDQT_MENU_H + +#include <libaudcore/objects.h> + +class QAction; +class QMenu; +class QMenuBar; +class QWidget; + +enum class AudMenuID; + +namespace audqt +{ + +typedef void (*MenuFunc)(); + +struct MenuItemText +{ + const char * name; + const char * icon; + const char * shortcut; +}; + +struct MenuItemConfig +{ + const char * sect; + const char * name; + const char * hook; +}; + +struct MenuItem +{ + MenuItemText text; + void (*func)(); + + /* for toggle items */ + MenuItemConfig cfg; + + /* for submenus */ + ArrayRef<MenuItem> items; + + /* for custom submenus */ + QMenu * (*submenu)(); + + /* for separators */ + bool sep; +}; + +constexpr MenuItem MenuCommand(MenuItemText text, MenuFunc func) +{ + return {text, func}; +} +constexpr MenuItem MenuToggle(MenuItemText text, MenuItemConfig cfg, + MenuFunc func = nullptr) +{ + return {text, func, cfg}; +} +constexpr MenuItem MenuSub(MenuItemText text, ArrayRef<MenuItem> items) +{ + return {text, nullptr, {}, items}; +} +constexpr MenuItem MenuSub(MenuItemText text, QMenu * (*submenu)()) +{ + return {text, nullptr, {}, nullptr, submenu}; +} +constexpr MenuItem MenuSep() +{ + return {{}, nullptr, {}, nullptr, nullptr, true}; +} + +/* menu.cc */ +QAction * menu_action(const MenuItem & menu_item, const char * domain, + QWidget * parent = nullptr); +QMenu * menu_build(ArrayRef<MenuItem> menu_items, const char * domain, + QWidget * parent = nullptr); +QMenuBar * menubar_build(ArrayRef<MenuItem> menu_items, const char * domain, + QWidget * parent = nullptr); + +#ifdef PACKAGE +static inline QMenu * menu_build(ArrayRef<MenuItem> menu_items, + QWidget * parent = nullptr) +{ + return menu_build(menu_items, PACKAGE, parent); +} +static inline QMenuBar * menubar_build(ArrayRef<MenuItem> menu_items, + QWidget * parent = nullptr) +{ + return menubar_build(menu_items, PACKAGE, parent); +} +#endif + +/* plugin-menu.cc */ +QMenu * menu_get_by_id(AudMenuID id); +void menu_add(AudMenuID id, MenuFunc func, const char * name, + const char * icon); +void menu_remove(AudMenuID id, MenuFunc func); + +} // namespace audqt + +#endif diff --git a/src/libaudqt/meson.build b/src/libaudqt/meson.build new file mode 100644 index 0000000..6aff2c9 --- /dev/null +++ b/src/libaudqt/meson.build @@ -0,0 +1,58 @@ +libaudqt_sources = [ + 'about-qt.cc', + 'art-qt.cc', + 'audqt.cc', + 'colorbutton.cc', + 'eq-preset-qt.cc', + 'equalizer-qt.cc', + 'file-entry.cc', + 'fileopener.cc', + 'font-entry.cc', + 'infopopup-qt.cc', + 'infowin-qt.cc', + 'info-widget.cc', + 'log-inspector.cc', + 'menu-qt.cc', + 'playlist-management.cc', + 'plugin-menu-qt.cc', + 'prefs-builder.cc', + 'prefs-plugin.cc', + 'prefs-widget-qt.cc', + 'prefs-window-qt.cc', + 'prefs-pluginlist-model.cc', + 'queue-manager-qt.cc', + 'url-opener-qt.cc', + 'util-qt.cc', + 'treeview.cc', + 'volumebutton.cc' +] + + +libaudqt_headers = [ + 'colorbutton.h', + 'export.h', + 'iface.h', + 'info-widget.h', + 'libaudqt.h', + 'menu.h', + 'treeview.h' +] + + +images_src = qt5.preprocess(qresources: 'images.qrc') + + +install_headers(libaudqt_headers, subdir: 'libaudqt') + + +libaudqt_lib = library('audqt', + libaudqt_sources, + images_src, + cpp_args: ['-DLIBAUDQT_BUILD'], + include_directories: [src_inc], + dependencies: [qt_dep], + link_with: [libaudcore_lib], + soversion: '2', + version: '2.2.0', + install: true +) diff --git a/src/libaudqt/playlist-management.cc b/src/libaudqt/playlist-management.cc new file mode 100644 index 0000000..d373801 --- /dev/null +++ b/src/libaudqt/playlist-management.cc @@ -0,0 +1,106 @@ +/* + * playlist-management.cc + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt.h" + +#include <QCheckBox> +#include <QInputDialog> +#include <QPushButton> + +#include <libaudcore/audstrings.h> +#include <libaudcore/i18n.h> +#include <libaudcore/playlist.h> +#include <libaudcore/runtime.h> + +namespace audqt +{ + +static QDialog * buildRenameDialog(Playlist playlist) +{ + auto dialog = new QInputDialog; + dialog->setInputMode(QInputDialog::TextInput); + dialog->setWindowTitle(_("Rename Playlist")); + dialog->setLabelText(_("What would you like to call this playlist?")); + dialog->setOkButtonText(translate_str(N_("_Rename"))); + dialog->setCancelButtonText(translate_str(N_("_Cancel"))); + dialog->setTextValue((const char *)playlist.get_title()); + + QObject::connect(dialog, &QInputDialog::textValueSelected, + [dialog, playlist](const QString & text) { + playlist.set_title(text.toUtf8()); + dialog->close(); + }); + + return dialog; +} + +static QDialog * buildDeleteDialog(Playlist playlist) +{ + auto dialog = new QMessageBox; + auto skip_prompt = + new QCheckBox(translate_str(N_("_Don’t ask again")), dialog); + auto remove = new QPushButton(translate_str(N_("_Remove")), dialog); + auto cancel = new QPushButton(translate_str(N_("_Cancel")), dialog); + + dialog->setIcon(QMessageBox::Question); + dialog->setWindowTitle(_("Remove Playlist")); + dialog->setText( + (const char *)str_printf(_("Do you want to permanently remove “%s”?"), + (const char *)playlist.get_title())); + dialog->setCheckBox(skip_prompt); + dialog->addButton(remove, QMessageBox::AcceptRole); + dialog->addButton(cancel, QMessageBox::RejectRole); + + remove->setIcon(audqt::get_icon("edit-delete")); + cancel->setIcon(audqt::get_icon("process-stop")); + + QObject::connect(skip_prompt, &QCheckBox::stateChanged, [](int state) { + aud_set_bool("audgui", "no_confirm_playlist_delete", + (state == Qt::Checked)); + }); + + QObject::connect(remove, &QPushButton::clicked, [dialog, playlist]() { + playlist.remove_playlist(); + dialog->close(); + }); + + return dialog; +} + +EXPORT void playlist_show_rename(Playlist playlist) +{ + auto dialog = buildRenameDialog(playlist); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); +} + +EXPORT void playlist_confirm_delete(Playlist playlist) +{ + if (aud_get_bool("audgui", "no_confirm_playlist_delete")) + { + playlist.remove_playlist(); + return; + } + + auto dialog = buildDeleteDialog(playlist); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); +} + +} // namespace audqt diff --git a/src/libaudqt/plugin-menu-qt.cc b/src/libaudqt/plugin-menu-qt.cc new file mode 100644 index 0000000..a886258 --- /dev/null +++ b/src/libaudqt/plugin-menu-qt.cc @@ -0,0 +1,91 @@ +/* + * plugin-menu.cc + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt.h" +#include "libaudqt/menu.h" + +#include <QMenu> + +#include <libaudcore/i18n.h> +#include <libaudcore/interface.h> +#include <libaudcore/plugins.h> + +namespace audqt +{ + +struct ItemData +{ + MenuItem item; + SmartPtr<QAction> action; +}; + +static aud::array<AudMenuID, Index<ItemData>> items; +static aud::array<AudMenuID, QMenu *> menus; + +static void show_prefs() { prefswin_show_plugin_page(PluginType::General); } + +MenuItem default_menu_items[] = { + MenuCommand({N_("_Plugins ..."), "preferences-system"}, show_prefs), +}; + +void menu_rebuild(AudMenuID id) +{ + if (menus[id]) + menus[id]->clear(); + else + menus[id] = new QMenu(_("Services")); + + for (auto & item : items[id]) + { + item.action.capture(menu_action(item.item, nullptr)); + menus[id]->addAction(item.action.get()); + } + + if (!menus[id]->isEmpty()) + menus[id]->addAction(menu_action(MenuSep(), PACKAGE, menus[id])); + + for (auto & item : default_menu_items) + menus[id]->addAction(menu_action(item, PACKAGE, menus[id])); +} + +EXPORT QMenu * menu_get_by_id(AudMenuID id) +{ + if (!menus[id]) + menu_rebuild(id); + + return menus[id]; +} + +EXPORT void menu_add(AudMenuID id, MenuFunc func, const char * name, + const char * icon) +{ + items[id].append(MenuCommand({name, icon}, func)); + + menu_rebuild(id); +} + +EXPORT void menu_remove(AudMenuID id, MenuFunc func) +{ + auto is_match = [func](ItemData & item) { return item.item.func == func; }; + + if (items[id].remove_if(is_match, true)) + menu_rebuild(id); +} + +} // namespace audqt diff --git a/src/libaudqt/prefs-builder.cc b/src/libaudqt/prefs-builder.cc new file mode 100644 index 0000000..ca9d111 --- /dev/null +++ b/src/libaudqt/prefs-builder.cc @@ -0,0 +1,232 @@ +/* + * prefs-builder.cc + * Copyright 2014 Ariadne Conill and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt.h" +#include "prefs-widget.h" + +#include <QButtonGroup> +#include <QFrame> +#include <QLayout> + +#include <libaudcore/i18n.h> +#include <libaudcore/preferences.h> +#include <libaudcore/runtime.h> + +namespace audqt +{ + +void prefs_populate(QBoxLayout * layout, ArrayRef<PreferencesWidget> widgets, + const char * domain) +{ + /* layout prior to header label */ + QBoxLayout * orig_layout = layout; + + /* layouts prior to check box */ + QBoxLayout * parent_layout = nullptr; + QBoxLayout * parent_orig_layout = nullptr; + + ParentWidget * parent_widget = nullptr; + QButtonGroup * radio_btn_group[2] = {nullptr, nullptr}; + + for (const PreferencesWidget & w : widgets) + { + if (w.child) + { + if (!parent_layout) + { + /* save prior layouts */ + parent_layout = layout; + parent_orig_layout = orig_layout; + + /* create new layout for child widgets */ + if (dynamic_cast<QHBoxLayout *>(parent_layout)) + layout = make_hbox(nullptr, sizes.TwoPt); + else + { + layout = make_vbox(nullptr, sizes.TwoPt); + layout->setContentsMargins(sizes.EightPt, 0, 0, 0); + } + + parent_layout->addLayout(layout); + + orig_layout = layout; + + if (parent_widget) + parent_widget->set_child_layout(layout); + } + } + else + { + if (parent_layout) + { + /* restore prior layouts */ + layout = parent_layout; + orig_layout = parent_orig_layout; + + parent_layout = nullptr; + parent_orig_layout = nullptr; + } + + /* enable/disable child widgets */ + if (parent_widget) + parent_widget->update_from_cfg(); + + parent_widget = nullptr; + } + + if (w.type != PreferencesWidget::RadioButton) + radio_btn_group[w.child] = nullptr; + if (!w.child) + radio_btn_group[true] = nullptr; + + switch (w.type) + { + case PreferencesWidget::Button: + layout->addWidget(new ButtonWidget(&w, domain)); + break; + + case PreferencesWidget::CheckButton: + { + auto checkbox = new BooleanWidget(&w, domain); + layout->addWidget(checkbox); + + if (!w.child) + parent_widget = checkbox; + + break; + } + + case PreferencesWidget::Label: + { + auto label = new QLabel(translate_str(w.label, domain)); + + if (strstr(w.label, "<b>")) + { + /* extra spacing above a header */ + if (orig_layout->itemAt(0)) + orig_layout->addSpacing(sizes.EightPt); + + orig_layout->addWidget(label); + + /* create indented layout below header */ + layout = make_vbox(nullptr, sizes.TwoPt); + layout->setContentsMargins(sizes.EightPt, 0, 0, 0); + orig_layout->addLayout(layout); + } + else + layout->addWidget(label); + + break; + } + + case PreferencesWidget::SpinButton: + switch (w.cfg.type) + { + case WidgetConfig::Int: + layout->addWidget(new IntegerWidget(&w, domain)); + break; + case WidgetConfig::Float: + layout->addWidget(new DoubleWidget(&w, domain)); + break; + default: + AUDDBG("encountered unhandled configuration type %d for " + "PreferencesWidget::SpinButton\n", + w.cfg.type); + break; + } + break; + + case PreferencesWidget::Entry: + layout->addWidget(new StringWidget(&w, domain)); + break; + + case PreferencesWidget::FileEntry: + layout->addWidget(new FileWidget(&w, domain)); + break; + + case PreferencesWidget::FontButton: + layout->addWidget(new FontWidget(&w, domain)); + break; + + case PreferencesWidget::RadioButton: + { + if (!radio_btn_group[w.child]) + radio_btn_group[w.child] = new QButtonGroup; + + auto radio_btn = + new RadioButtonWidget(&w, domain, radio_btn_group[w.child]); + layout->addWidget(radio_btn); + + if (!w.child) + parent_widget = radio_btn; + + break; + } + + case PreferencesWidget::ComboBox: + layout->addWidget(new ComboBoxWidget(&w, domain)); + break; + + case PreferencesWidget::CustomQt: + if (w.data.populate) + layout->addWidget((QWidget *)w.data.populate()); + break; + + /* layout widgets follow */ + case PreferencesWidget::Box: + layout->addWidget(new BoxWidget( + &w, domain, (bool)dynamic_cast<QHBoxLayout *>(layout))); + break; + + case PreferencesWidget::Table: + layout->addWidget(new TableWidget(&w, domain)); + break; + + case PreferencesWidget::Notebook: + layout->addWidget(new NotebookWidget(&w, domain)); + break; + + case PreferencesWidget::Separator: + { + QFrame * f = new QFrame; + f->setFrameShape(w.data.separator.horizontal ? QFrame::HLine + : QFrame::VLine); + f->setFrameShadow(QFrame::Sunken); + + layout->addSpacing(sizes.FourPt); + layout->addWidget(f); + layout->addSpacing(sizes.FourPt); + + break; + } + + /* stub handler */ + default: + AUDDBG("invoked stub handler for PreferencesWidget type %d\n", + w.type); + break; + } + } + + /* enable/disable child widgets */ + if (parent_widget) + parent_widget->update_from_cfg(); +} + +} // namespace audqt diff --git a/src/libaudqt/prefs-plugin.cc b/src/libaudqt/prefs-plugin.cc new file mode 100644 index 0000000..a7f6e94 --- /dev/null +++ b/src/libaudqt/prefs-plugin.cc @@ -0,0 +1,164 @@ +/* + * prefs-plugin.cc + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <memory> + +#include <QDialog> +#include <QDialogButtonBox> +#include <QPointer> +#include <QPushButton> +#include <QVBoxLayout> + +#include <libaudcore/audstrings.h> +#include <libaudcore/i18n.h> +#include <libaudcore/plugin.h> +#include <libaudcore/plugins.h> +#include <libaudcore/preferences.h> +#include <libaudcore/runtime.h> + +#include "libaudqt-internal.h" +#include "libaudqt.h" + +namespace audqt +{ + +EXPORT void plugin_about(PluginHandle * ph) +{ + Plugin * header = (Plugin *)aud_plugin_get_header(ph); + + if (!header) + return; + + const char * name = header->info.name; + const char * text = header->info.about; + if (!text) + return; + + if (header->info.domain) + { + name = dgettext(header->info.domain, name); + text = dgettext(header->info.domain, text); + } + + AUDDBG("name = %s\n", name); + + simple_message(str_printf(_("About %s"), name), text, + QMessageBox::Information); +} + +struct ConfigWindow +{ + PluginHandle * ph; + QPointer<QDialog> root; + + ~ConfigWindow() { delete root; } +}; + +static Index<std::unique_ptr<ConfigWindow>> config_windows; + +static ConfigWindow * find_config_window(PluginHandle * ph) +{ + for (auto & cw : config_windows) + { + if (cw && cw->ph == ph) + return cw.get(); + } + + return nullptr; +} + +EXPORT void plugin_prefs(PluginHandle * ph) +{ + ConfigWindow * cw = find_config_window(ph); + + if (cw && cw->root) + { + window_bring_to_front(cw->root); + return; + } + + Plugin * header = (Plugin *)aud_plugin_get_header(ph); + if (!header) + return; + + const PluginPreferences * p = header->info.prefs; + if (!p) + return; + + if (!cw) + { + cw = new ConfigWindow{ph}; + config_windows.append(cw); + } + + cw->root = new QDialog; + cw->root->setAttribute(Qt::WA_DeleteOnClose); + cw->root->setContentsMargins(margins.FourPt); + + if (p->init) + p->init(); + + QObject::connect(cw->root.data(), &QObject::destroyed, [p]() { + if (p->cleanup) + p->cleanup(); + }); + + const char * name = header->info.name; + if (header->info.domain) + name = dgettext(header->info.domain, name); + + cw->root->setWindowTitle((const char *)str_printf(_("%s Settings"), name)); + + auto vbox = make_vbox(cw->root, sizes.TwoPt); + prefs_populate(vbox, p->widgets, header->info.domain); + vbox->addStretch(1); + + QDialogButtonBox * bbox = new QDialogButtonBox; + + if (p->apply) + { + bbox->setStandardButtons(QDialogButtonBox::Ok | + QDialogButtonBox::Cancel); + bbox->button(QDialogButtonBox::Ok)->setText(translate_str(N_("_Set"))); + bbox->button(QDialogButtonBox::Cancel) + ->setText(translate_str(N_("_Cancel"))); + + QObject::connect(bbox, &QDialogButtonBox::accepted, [p, cw]() { + p->apply(); + cw->root->deleteLater(); + }); + } + else + { + bbox->setStandardButtons(QDialogButtonBox::Close); + bbox->button(QDialogButtonBox::Close) + ->setText(translate_str(N_("_Close"))); + } + + QObject::connect(bbox, &QDialogButtonBox::rejected, cw->root.data(), + &QObject::deleteLater); + + vbox->addWidget(bbox); + + window_bring_to_front(cw->root); +} + +void plugin_prefs_hide(void) { config_windows.clear(); } + +} // namespace audqt diff --git a/src/libaudqt/prefs-pluginlist-model.cc b/src/libaudqt/prefs-pluginlist-model.cc new file mode 100644 index 0000000..df6fd4a --- /dev/null +++ b/src/libaudqt/prefs-pluginlist-model.cc @@ -0,0 +1,196 @@ +/* + * prefs-pluginlist-model.cc + * Copyright 2014-2017 John Lindgren and Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "prefs-pluginlist-model.h" + +#include <QIcon> + +#include <libaudcore/i18n.h> +#include <libaudcore/plugins.h> +#include <libaudcore/runtime.h> +#include <libaudqt/libaudqt.h> + +namespace audqt +{ + +struct PluginCategory +{ + PluginType type; + const char * name; +}; + +static const PluginCategory categories[] = { + {PluginType::General, N_("General")}, + {PluginType::Effect, N_("Effect")}, + {PluginType::Vis, N_("Visualization")}, + {PluginType::Input, N_("Input")}, + {PluginType::Playlist, N_("Playlist")}, + {PluginType::Transport, N_("Transport")}}; + +static constexpr int n_categories = aud::n_elems(categories); + +// The model hierarchy is as follows: +// +// Root (invalid index) +// + General category (index with row 0, null internal pointer) +// + General plugin (index with row 0, internal pointer to PluginHandle) +// + General plugin (index with row 1, internal pointer to PluginHandle) +// + General plugin ... +// + Effect category (index with row 1, null internal pointer) +// + Effect plugin ... +// + More categories ... + +QModelIndex PluginListModel::index(int row, int column, + const QModelIndex & parent) const +{ + // is parent the root node? + if (!parent.isValid()) + return createIndex(row, column, nullptr); + + // is parent a plugin node? + if (parent.internalPointer() != nullptr) + return QModelIndex(); + + // parent must be a category node + int cat = parent.row(); + if (cat < 0 || cat >= n_categories) + return QModelIndex(); + + auto & list = aud_plugin_list(categories[cat].type); + if (row < 0 || row >= list.len()) + return QModelIndex(); + + return createIndex(row, column, list[row]); +} + +// for a plugin node, return the category node +// for all other nodes, return an invalid index +QModelIndex PluginListModel::parent(const QModelIndex & child) const +{ + auto p = pluginForIndex(child); + return p ? indexForType(aud_plugin_get_type(p)) : QModelIndex(); +} + +// retrieve the PluginHandle from a plugin node +PluginHandle * PluginListModel::pluginForIndex(const QModelIndex & index) const +{ + return (PluginHandle *)index.internalPointer(); +} + +// look up the category node for a given plugin type +QModelIndex PluginListModel::indexForType(PluginType type) const +{ + for (int cat = 0; cat < n_categories; cat++) + { + if (categories[cat].type == type) + return createIndex(cat, 0, nullptr); + } + + return QModelIndex(); +} + +int PluginListModel::rowCount(const QModelIndex & parent) const +{ + // for the root node, return the # of categories + if (!parent.isValid()) + return n_categories; + + // for a plugin node, return 0 (no children) + if (parent.internalPointer() != nullptr) + return 0; + + // for a category node, return the # of plugins + int cat = parent.row(); + if (cat < 0 || cat >= n_categories) + return 0; + + return aud_plugin_list(categories[cat].type).len(); +} + +int PluginListModel::columnCount(const QModelIndex & parent) const +{ + return NumColumns; +} + +QVariant PluginListModel::data(const QModelIndex & index, int role) const +{ + auto p = pluginForIndex(index); + + if (!p) // category node? + { + if (role != Qt::DisplayRole || index.column() != 0) + return QVariant(); + + int cat = index.row(); + if (cat < 0 || cat >= n_categories) + return QVariant(); + + return QString(_(categories[cat].name)); + } + + bool enabled = aud_plugin_get_enabled(p); + + switch (index.column()) + { + case NameColumn: + if (role == Qt::DisplayRole) + return QString(aud_plugin_get_name(p)); + if (role == Qt::CheckStateRole) + return enabled ? Qt::Checked : Qt::Unchecked; + + break; + + case AboutColumn: + if (role == Qt::DecorationRole && enabled && aud_plugin_has_about(p)) + return audqt::get_icon("dialog-information"); + + break; + + case SettingsColumn: + if (role == Qt::DecorationRole && enabled && + aud_plugin_has_configure(p)) + return audqt::get_icon("preferences-system"); + + break; + } + + return QVariant(); +} + +bool PluginListModel::setData(const QModelIndex & index, const QVariant & value, + int role) +{ + if (role != Qt::CheckStateRole) + return false; + + auto p = pluginForIndex(index); + if (!p) + return false; + + aud_plugin_enable(p, value.toUInt() != Qt::Unchecked); + emit dataChanged(index, index.sibling(index.row(), NumColumns - 1)); + return true; +} + +Qt::ItemFlags PluginListModel::flags(const QModelIndex & index) const +{ + return (Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); +} + +} // namespace audqt diff --git a/src/libaudqt/prefs-pluginlist-model.h b/src/libaudqt/prefs-pluginlist-model.h new file mode 100644 index 0000000..74438a9 --- /dev/null +++ b/src/libaudqt/prefs-pluginlist-model.h @@ -0,0 +1,61 @@ +/* + * prefs-pluginlist-model.h + * Copyright 2014-2017 John Lindgren and Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef PREFS_PLUGINLIST_MODEL_H +#define PREFS_PLUGINLIST_MODEL_H + +#include <QAbstractItemModel> + +enum class PluginType; +class PluginHandle; + +namespace audqt +{ + +class PluginListModel : public QAbstractItemModel +{ +public: + enum + { + NameColumn, + AboutColumn, + SettingsColumn, + SpacerColumn, + NumColumns + }; + + PluginListModel(QObject * parent) : QAbstractItemModel(parent) {} + + QModelIndex index(int row, int column, const QModelIndex & parent) const; + QModelIndex parent(const QModelIndex & child) const; + + PluginHandle * pluginForIndex(const QModelIndex & index) const; + QModelIndex indexForType(PluginType type) const; + + int rowCount(const QModelIndex & parent) const; + int columnCount(const QModelIndex & parent) const; + + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex & index, const QVariant & value, int role); + Qt::ItemFlags flags(const QModelIndex & parent) const; +}; + +} // namespace audqt + +#endif diff --git a/src/libaudqt/prefs-widget-qt.cc b/src/libaudqt/prefs-widget-qt.cc new file mode 100644 index 0000000..1a21b06 --- /dev/null +++ b/src/libaudqt/prefs-widget-qt.cc @@ -0,0 +1,431 @@ +/* + * prefs-widget.cc + * Copyright 2007-2014 Tomasz Moń, Ariadne Conill, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt.h" +#include "prefs-widget.h" + +#include <assert.h> +#include <math.h> + +#include <QButtonGroup> +#include <QComboBox> +#include <QHBoxLayout> +#include <QLineEdit> +#include <QSpinBox> +#include <QVBoxLayout> + +#include <libaudcore/audstrings.h> +#include <libaudcore/i18n.h> + +namespace audqt +{ + +HookableWidget::HookableWidget(const PreferencesWidget * parent, + const char * domain) + : m_parent(parent), m_domain(domain) +{ + if (m_parent->cfg.hook) + hook.capture(new HookReceiver<HookableWidget>{ + m_parent->cfg.hook, this, &HookableWidget::update_from_cfg}); +} + +void HookableWidget::update_from_cfg() +{ + m_updating = true; + update(); + m_updating = false; +} + +/* button */ +ButtonWidget::ButtonWidget(const PreferencesWidget * parent, + const char * domain) + : QPushButton(translate_str(parent->label, domain)) +{ + setAutoDefault(false); + QObject::connect(this, &QPushButton::clicked, parent->data.button.callback); +} + +/* boolean widget (checkbox) */ +BooleanWidget::BooleanWidget(const PreferencesWidget * parent, + const char * domain) + : QCheckBox(translate_str(parent->label, domain)), + ParentWidget(parent, domain) +{ + update(); + + QObject::connect(this, &QCheckBox::stateChanged, [this](int state) { + if (m_updating) + return; + m_parent->cfg.set_bool(state != Qt::Unchecked); + if (m_child_layout) + enable_layout(m_child_layout, state != Qt::Unchecked); + }); +} + +void BooleanWidget::update() +{ + bool on = m_parent->cfg.get_bool(); + setCheckState(on ? Qt::Checked : Qt::Unchecked); + if (m_child_layout) + enable_layout(m_child_layout, on); +} + +/* integer (radio button) */ +RadioButtonWidget::RadioButtonWidget(const PreferencesWidget * parent, + const char * domain, + QButtonGroup * btn_group) + : QRadioButton(translate_str(parent->label, domain)), + ParentWidget(parent, domain) +{ + if (btn_group) + btn_group->addButton(this, parent->data.radio_btn.value); + + update(); + + QObject::connect(this, &QAbstractButton::toggled, [this](bool checked) { + if (m_updating) + return; + if (checked) + m_parent->cfg.set_int(m_parent->data.radio_btn.value); + if (m_child_layout) + enable_layout(m_child_layout, checked); + }); +} + +void RadioButtonWidget::update() +{ + bool checked = (m_parent->cfg.get_int() == m_parent->data.radio_btn.value); + if (checked) + setChecked(true); + if (m_child_layout) + enable_layout(m_child_layout, checked); +} + +/* integer (spinbox) */ +IntegerWidget::IntegerWidget(const PreferencesWidget * parent, + const char * domain) + : HookableWidget(parent, domain), m_spinner(new QSpinBox) +{ + auto layout = make_hbox(this); + + if (parent->label) + layout->addWidget(new QLabel(translate_str(parent->label, domain))); + + m_spinner->setRange((int)m_parent->data.spin_btn.min, + (int)m_parent->data.spin_btn.max); + m_spinner->setSingleStep((int)m_parent->data.spin_btn.step); + layout->addWidget(m_spinner); + + if (parent->data.spin_btn.right_label) + layout->addWidget(new QLabel( + translate_str(parent->data.spin_btn.right_label, domain))); + + layout->addStretch(1); + + update(); + + /* + * Qt has two different valueChanged signals for spin boxes. So we have to + * do an explicit cast to the type of the correct valueChanged signal. + * --kaniini. + */ + void (QSpinBox::*signal)(int) = &QSpinBox::valueChanged; + QObject::connect(m_spinner, signal, [this](int value) { + if (!m_updating) + m_parent->cfg.set_int(value); + }); +} + +void IntegerWidget::update() { m_spinner->setValue(m_parent->cfg.get_int()); } + +/* double (spinbox) */ +DoubleWidget::DoubleWidget(const PreferencesWidget * parent, + const char * domain) + : HookableWidget(parent, domain), m_spinner(new QDoubleSpinBox) +{ + auto layout = make_hbox(this); + + if (parent->label) + layout->addWidget(new QLabel(translate_str(parent->label, domain))); + + auto decimals_for = [](double step) { + return aud::max(0, -(int)floor(log10(step) + 0.01)); + }; + + m_spinner->setDecimals(decimals_for(m_parent->data.spin_btn.step)); + m_spinner->setRange(m_parent->data.spin_btn.min, + m_parent->data.spin_btn.max); + m_spinner->setSingleStep(m_parent->data.spin_btn.step); + layout->addWidget(m_spinner); + + if (parent->data.spin_btn.right_label) + layout->addWidget(new QLabel( + translate_str(parent->data.spin_btn.right_label, domain))); + + layout->addStretch(1); + + update(); + + void (QDoubleSpinBox::*signal)(double) = &QDoubleSpinBox::valueChanged; + QObject::connect(m_spinner, signal, [this](double value) { + if (!m_updating) + m_parent->cfg.set_float(value); + }); +} + +void DoubleWidget::update() { m_spinner->setValue(m_parent->cfg.get_float()); } + +/* string (lineedit) */ +StringWidget::StringWidget(const PreferencesWidget * parent, + const char * domain) + : HookableWidget(parent, domain), m_lineedit(new QLineEdit) +{ + auto layout = make_hbox(this); + + if (parent->label) + layout->addWidget(new QLabel(translate_str(parent->label, domain))); + + if (parent->type == PreferencesWidget::Entry && parent->data.entry.password) + m_lineedit->setEchoMode(QLineEdit::Password); + + layout->addWidget(m_lineedit, 1); + + update(); + + QObject::connect(m_lineedit, &QLineEdit::textChanged, + [this](const QString & value) { + if (!m_updating) + m_parent->cfg.set_string(value.toUtf8()); + }); +} + +void StringWidget::update() +{ + m_lineedit->setText((const char *)m_parent->cfg.get_string()); +} + +/* file widget (audqt::FileEntry) */ +FileWidget::FileWidget(const PreferencesWidget * parent, const char * domain) + : HookableWidget(parent, domain) +{ + QFileDialog::FileMode file_mode; + const char * title; + + switch (parent->data.file_entry.mode) + { + default: + case FileSelectMode::File: + file_mode = QFileDialog::ExistingFile; + title = _("Choose File"); + break; + case FileSelectMode::Folder: + file_mode = QFileDialog::Directory; + title = _("Choose Folder"); + break; + } + + m_lineedit = + file_entry_new(this, title, file_mode, QFileDialog::AcceptOpen); + + auto layout = make_hbox(this); + + if (parent->label) + layout->addWidget(new QLabel(translate_str(parent->label, domain))); + + layout->addWidget(m_lineedit, 1); + + update(); + + QObject::connect( + m_lineedit, &QLineEdit::textChanged, [this](const QString &) { + if (!m_updating) + m_parent->cfg.set_string(file_entry_get_uri(m_lineedit)); + }); +} + +void FileWidget::update() +{ + file_entry_set_uri(m_lineedit, m_parent->cfg.get_string()); +} + +/* font widget (audqt::FontEntry) */ +FontWidget::FontWidget(const PreferencesWidget * parent, const char * domain) + : HookableWidget(parent, domain), m_lineedit(font_entry_new(this, nullptr)) +{ + auto layout = make_hbox(this); + + if (parent->label) + layout->addWidget(new QLabel(translate_str(parent->label, domain))); + + layout->addWidget(m_lineedit, 1); + + update(); + + QObject::connect(m_lineedit, &QLineEdit::textChanged, + [this](const QString & value) { + if (!m_updating) + m_parent->cfg.set_string(value.toUtf8()); + }); +} + +void FontWidget::update() +{ + m_lineedit->setText((const char *)m_parent->cfg.get_string()); +} + +/* combo box widget (string or int) */ +ComboBoxWidget::ComboBoxWidget(const PreferencesWidget * parent, + const char * domain) + : HookableWidget(parent, domain), m_combobox(new QComboBox) +{ + auto layout = make_hbox(this); + + if (parent->label) + layout->addWidget(new QLabel(translate_str(parent->label, domain))); + + layout->addWidget(m_combobox); + layout->addStretch(1); + + update(); + + void (QComboBox::*signal)(int) = &QComboBox::currentIndexChanged; + QObject::connect(m_combobox, signal, [this](int idx) { + if (m_updating) + return; + + QVariant data = m_combobox->itemData(idx); + + switch (m_parent->cfg.type) + { + case WidgetConfig::Int: + m_parent->cfg.set_int(data.toInt()); + break; + case WidgetConfig::String: + m_parent->cfg.set_string(data.toString().toUtf8()); + break; + default: + break; + } + }); +} + +void ComboBoxWidget::update() +{ + ArrayRef<ComboItem> items = m_parent->data.combo.elems; + + if (m_parent->data.combo.fill) + items = m_parent->data.combo.fill(); + + m_combobox->clear(); + + /* add combobox items */ + switch (m_parent->cfg.type) + { + case WidgetConfig::Int: + for (const ComboItem & item : items) + m_combobox->addItem(dgettext(m_domain, item.label), item.num); + break; + case WidgetConfig::String: + for (const ComboItem & item : items) + m_combobox->addItem(dgettext(m_domain, item.label), item.str); + break; + default: + break; + } + + /* set selected index */ + switch (m_parent->cfg.type) + { + case WidgetConfig::Int: + { + int num = m_parent->cfg.get_int(); + + for (int i = 0; i < items.len; i++) + { + if (items.data[i].num == num) + { + m_combobox->setCurrentIndex(i); + break; + } + } + + break; + } + case WidgetConfig::String: + { + String str = m_parent->cfg.get_string(); + + for (int i = 0; i < items.len; i++) + { + if (!strcmp_safe(items.data[i].str, str)) + { + m_combobox->setCurrentIndex(i); + break; + } + } + + break; + } + default: + break; + } +} + +/* layout widgets */ +BoxWidget::BoxWidget(const PreferencesWidget * parent, const char * domain, + bool horizontal_layout) +{ + QBoxLayout * layout; + if (parent->data.box.horizontal) + layout = make_hbox(this, sizes.TwoPt); + else + layout = make_vbox(this, sizes.TwoPt); + + prefs_populate(layout, parent->data.box.widgets, domain); + + /* only add stretch if the orientation does not match the enclosing layout + */ + if (parent->data.box.horizontal != horizontal_layout) + layout->addStretch(1); +} + +TableWidget::TableWidget(const PreferencesWidget * parent, const char * domain) +{ + // TODO: proper table layout + auto layout = make_vbox(this, sizes.TwoPt); + prefs_populate(layout, parent->data.table.widgets, domain); +} + +NotebookWidget::NotebookWidget(const PreferencesWidget * parent, + const char * domain) +{ + for (const NotebookTab & tab : parent->data.notebook.tabs) + { + auto widget = new QWidget(this); + widget->setContentsMargins(margins.FourPt); + + auto layout = make_vbox(widget, sizes.TwoPt); + prefs_populate(layout, tab.widgets, domain); + layout->addStretch(1); + + addTab(widget, translate_str(tab.name, domain)); + } +} + +} // namespace audqt diff --git a/src/libaudqt/prefs-widget.h b/src/libaudqt/prefs-widget.h new file mode 100644 index 0000000..e796ae7 --- /dev/null +++ b/src/libaudqt/prefs-widget.h @@ -0,0 +1,194 @@ +/* + * prefs-widget.cc + * Copyright 2007-2014 Tomasz Moń, Ariadne Conill, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDQT_PREFS_WIDGET_H +#define LIBAUDQT_PREFS_WIDGET_H + +#include <libaudcore/hook.h> +#include <libaudcore/preferences.h> + +#include <QCheckBox> +#include <QLabel> +#include <QPushButton> +#include <QRadioButton> +#include <QTabWidget> + +class QButtonGroup; +class QComboBox; +class QDoubleSpinBox; +class QLineEdit; +class QSpinBox; + +namespace audqt +{ + +/* base class which provides plumbing for hooks. */ +class HookableWidget +{ +public: + void update_from_cfg(); + +protected: + HookableWidget(const PreferencesWidget * parent, const char * domain); + + virtual ~HookableWidget() {} + virtual void update() {} + + const PreferencesWidget * const m_parent; + const char * const m_domain; + bool m_updating = false; + +private: + SmartPtr<HookReceiver<HookableWidget>> hook; +}; + +/* shared class which allows disabling child widgets */ +class ParentWidget : public HookableWidget +{ +public: + void set_child_layout(QLayout * layout) { m_child_layout = layout; } + +protected: + ParentWidget(const PreferencesWidget * parent, const char * domain) + : HookableWidget(parent, domain) + { + } + + QLayout * m_child_layout = nullptr; +}; + +/* button widget */ +class ButtonWidget : public QPushButton +{ +public: + ButtonWidget(const PreferencesWidget * parent, const char * domain); +}; + +/* boolean widget (checkbox) */ +class BooleanWidget : public QCheckBox, public ParentWidget +{ +public: + BooleanWidget(const PreferencesWidget * parent, const char * domain); + +private: + void update(); +}; + +/* integer widget (spinner) */ +class IntegerWidget : public QWidget, HookableWidget +{ +public: + IntegerWidget(const PreferencesWidget * parent, const char * domain); + +private: + void update(); + QSpinBox * m_spinner; +}; + +/* integer widget (radio button) */ +class RadioButtonWidget : public QRadioButton, public ParentWidget +{ +public: + RadioButtonWidget(const PreferencesWidget * parent, const char * domain, + QButtonGroup * btn_group); + +private: + void update(); +}; + +/* double widget (spinner) */ +class DoubleWidget : public QWidget, HookableWidget +{ +public: + DoubleWidget(const PreferencesWidget * parent, const char * domain); + +private: + void update(); + QDoubleSpinBox * m_spinner; +}; + +/* string widget (lineedit) */ +class StringWidget : public QWidget, HookableWidget +{ +public: + StringWidget(const PreferencesWidget * parent, const char * domain); + +private: + void update(); + QLineEdit * m_lineedit; +}; + +/* file widget (audqt::FileEntry) */ +class FileWidget : public QWidget, HookableWidget +{ +public: + FileWidget(const PreferencesWidget * parent, const char * domain); + +private: + void update(); + QLineEdit * m_lineedit; +}; + +/* font widget (audqt::FontEntry) */ +class FontWidget : public QWidget, HookableWidget +{ +public: + FontWidget(const PreferencesWidget * parent, const char * domain); + +private: + void update(); + QLineEdit * m_lineedit; +}; + +/* combo box (string or int) */ +class ComboBoxWidget : public QWidget, HookableWidget +{ +public: + ComboBoxWidget(const PreferencesWidget * parent, const char * domain); + +private: + void update(); + QComboBox * m_combobox; +}; + +/* box container widget */ +class BoxWidget : public QWidget +{ +public: + BoxWidget(const PreferencesWidget * parent, const char * domain, + bool horizontal_layout); +}; + +/* table container widget */ +class TableWidget : public QWidget +{ +public: + TableWidget(const PreferencesWidget * parent, const char * domain); +}; + +/* notebook widget */ +class NotebookWidget : public QTabWidget +{ +public: + NotebookWidget(const PreferencesWidget * parent, const char * domain); +}; + +} // namespace audqt + +#endif diff --git a/src/libaudqt/prefs-window-qt.cc b/src/libaudqt/prefs-window-qt.cc new file mode 100644 index 0000000..96ef3ab --- /dev/null +++ b/src/libaudqt/prefs-window-qt.cc @@ -0,0 +1,766 @@ +/* + * prefs-window.cc + * Copyright 2006-2014 Ariadne Conill, Tomasz Moń, Michael Färber, and + * John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <QAction> +#include <QCheckBox> +#include <QComboBox> +#include <QDialog> +#include <QDialogButtonBox> +#include <QGridLayout> +#include <QHeaderView> +#include <QIcon> +#include <QItemSelectionModel> +#include <QLabel> +#include <QLineEdit> +#include <QMenu> +#include <QPushButton> +#include <QSignalMapper> +#include <QStackedWidget> +#include <QTabWidget> +#include <QToolBar> +#include <QTreeView> +#include <QVBoxLayout> + +#include <libaudcore/audstrings.h> +#include <libaudcore/drct.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/mainloop.h> +#include <libaudcore/playlist.h> +#include <libaudcore/plugin.h> +#include <libaudcore/plugins.h> +#include <libaudcore/preferences.h> +#include <libaudcore/runtime.h> + +#include "libguess/libguess.h" + +#include "libaudqt.h" +#include "prefs-pluginlist-model.h" + +namespace audqt +{ + +class PrefsWindow : public QDialog +{ +public: + static PrefsWindow * get_instance() + { + if (!instance) + (void)new PrefsWindow; + return instance; + } + + static void destroy_instance() + { + if (instance) + delete instance; + } + + static ArrayRef<ComboItem> get_output_combo() + { + return {instance->output_combo_elements.begin(), + instance->output_combo_elements.len()}; + } + + static int output_combo_selected; + static void output_combo_changed() { instance->output_change(); } + + static void * get_output_config_button() + { + return instance->output_config_button; + } + static void * get_output_about_button() + { + return instance->output_about_button; + } + + static void * get_record_checkbox() { return instance->record_checkbox; } + static void * get_record_config_button() + { + return instance->record_config_button; + } + static void * get_record_about_button() + { + return instance->record_about_button; + } + +private: + static PrefsWindow * instance; + + PrefsWindow(); + ~PrefsWindow() { instance = nullptr; } + + Index<ComboItem> output_combo_elements; + QPushButton *output_config_button, *output_about_button; + + QCheckBox * record_checkbox; + QPushButton *record_config_button, *record_about_button; + + void output_setup(); + void output_change(); + + void record_setup(); + void record_update(); + + const HookReceiver<PrefsWindow> record_hook{"enable record", this, + &PrefsWindow::record_update}; +}; + +/* static data */ +PrefsWindow * PrefsWindow::instance = nullptr; +int PrefsWindow::output_combo_selected; + +struct Category +{ + const char * icon; + const char * name; +}; + +struct TitleFieldTag +{ + const char * name; + const char * tag; +}; + +enum +{ + CATEGORY_APPEARANCE = 0, + CATEGORY_AUDIO, + CATEGORY_NETWORK, + CATEGORY_PLAYLIST, + CATEGORY_SONG_INFO, + CATEGORY_PLUGINS, + CATEGORY_ADVANCED, + CATEGORY_COUNT +}; + +static const Category categories[] = { + {"applications-graphics", N_("Appearance")}, + {"audio-volume-medium", N_("Audio")}, + {"applications-internet", N_("Network")}, + {"audio-x-generic", N_("Playlist")}, + {"dialog-information", N_("Song Info")}, + {"applications-system", N_("Plugins")}, + {"preferences-system", N_("Advanced")}}; + +static const TitleFieldTag title_field_tags[] = { + {N_("Artist"), "${artist}"}, + {N_("Album"), "${album}"}, + {N_("Album artist"), "${album-artist}"}, + {N_("Title"), "${title}"}, + {N_("Track number"), "${track-number}"}, + {N_("Genre"), "${genre}"}, + {N_("File name"), "${file-name}"}, + {N_("File path"), "${file-path}"}, + {N_("Date"), "${date}"}, + {N_("Description"), "${description}"}, + {N_("Year"), "${year}"}, + {N_("Comment"), "${comment}"}, + {N_("Codec"), "${codec}"}, + {N_("Quality"), "${quality}"}}; + +static const ComboItem chardet_detector_presets[] = { + ComboItem(N_("None"), ""), + ComboItem(N_("Arabic"), GUESS_REGION_AR), + ComboItem(N_("Baltic"), GUESS_REGION_BL), + ComboItem(N_("Chinese"), GUESS_REGION_CN), + ComboItem(N_("Greek"), GUESS_REGION_GR), + ComboItem(N_("Hebrew"), GUESS_REGION_HW), + ComboItem(N_("Japanese"), GUESS_REGION_JP), + ComboItem(N_("Korean"), GUESS_REGION_KR), + ComboItem(N_("Polish"), GUESS_REGION_PL), + ComboItem(N_("Russian"), GUESS_REGION_RU), + ComboItem(N_("Taiwanese"), GUESS_REGION_TW), + ComboItem(N_("Turkish"), GUESS_REGION_TR)}; + +static const ComboItem bitdepth_elements[] = { + ComboItem(N_("Automatic"), -1), ComboItem("16", 16), ComboItem("24", 24), + ComboItem("32", 32), ComboItem(N_("Floating point"), 0)}; + +static const ComboItem record_elements[] = { + ComboItem(N_("As decoded"), (int)OutputStream::AsDecoded), + ComboItem(N_("After applying ReplayGain"), + (int)OutputStream::AfterReplayGain), + ComboItem(N_("After applying effects"), (int)OutputStream::AfterEffects), + ComboItem(N_("After applying equalization"), + (int)OutputStream::AfterEqualizer)}; + +static const ComboItem replaygainmode_elements[] = { + ComboItem(N_("Track"), (int)ReplayGainMode::Track), + ComboItem(N_("Album"), (int)ReplayGainMode::Album), + ComboItem(N_("Based on shuffle"), (int)ReplayGainMode::Automatic)}; + +static Index<ComboItem> iface_combo_elements; +static int iface_combo_selected; +static QWidget * iface_prefs_box; + +static ArrayRef<ComboItem> iface_combo_fill(); +static void iface_combo_changed(); +static void * iface_create_prefs_box(); + +static const PreferencesWidget appearance_page_widgets[] = { + WidgetCombo(N_("Interface:"), + WidgetInt(iface_combo_selected, iface_combo_changed), + {0, iface_combo_fill}), + WidgetSeparator({true}), WidgetCustomQt(iface_create_prefs_box)}; + +static void output_bit_depth_changed(); + +static const PreferencesWidget output_combo_widgets[] = { + WidgetCombo(N_("Output plugin:"), + WidgetInt(PrefsWindow::output_combo_selected, + PrefsWindow::output_combo_changed, + "audqt update output combo"), + {0, PrefsWindow::get_output_combo}), + WidgetCustomQt(PrefsWindow::get_output_config_button), + WidgetCustomQt(PrefsWindow::get_output_about_button)}; + +static const PreferencesWidget record_buttons[] = { + WidgetCustomQt(PrefsWindow::get_record_config_button), + WidgetCustomQt(PrefsWindow::get_record_about_button)}; + +static const PreferencesWidget gain_table[] = { + WidgetSpin(N_("Amplify all files:"), WidgetFloat(0, "replay_gain_preamp"), + {-15, 15, 0.1, N_("dB")}), + WidgetSpin(N_("Amplify untagged files:"), WidgetFloat(0, "default_gain"), + {-15, 15, 0.1, N_("dB")})}; + +static const PreferencesWidget audio_page_widgets[] = { + WidgetLabel(N_("<b>Output Settings</b>")), + WidgetBox({{output_combo_widgets}, true}), + WidgetCombo(N_("Bit depth:"), + WidgetInt(0, "output_bit_depth", output_bit_depth_changed), + {{bitdepth_elements}}), + WidgetSpin(N_("Buffer size:"), WidgetInt(0, "output_buffer_size"), + {100, 10000, 1000, N_("ms")}), + WidgetCheck(N_("Soft clipping"), WidgetBool(0, "soft_clipping")), + WidgetCheck(N_("Use software volume control (not recommended)"), + WidgetBool(0, "software_volume_control")), + WidgetLabel(N_("<b>Recording Settings</b>")), + WidgetCustomQt(PrefsWindow::get_record_checkbox), + WidgetBox({{record_buttons}, true}, WIDGET_CHILD), + WidgetCombo(N_("Record stream:"), WidgetInt(0, "record_stream"), + {{record_elements}}), + WidgetLabel(N_("<b>ReplayGain</b>")), + WidgetCheck(N_("Enable ReplayGain"), WidgetBool(0, "enable_replay_gain")), + WidgetCombo(N_("Mode:"), WidgetInt(0, "replay_gain_mode"), + {{replaygainmode_elements}}, WIDGET_CHILD), + WidgetCheck(N_("Prevent clipping (recommended)"), + WidgetBool(0, "enable_clipping_prevention"), WIDGET_CHILD), + WidgetTable({{gain_table}}, WIDGET_CHILD)}; + +static const PreferencesWidget proxy_host_port_elements[] = { + WidgetEntry(N_("Proxy hostname:"), WidgetString(0, "proxy_host")), + WidgetEntry(N_("Proxy port:"), WidgetString(0, "proxy_port"))}; + +static const PreferencesWidget proxy_auth_elements[] = { + WidgetEntry(N_("Proxy username:"), WidgetString(0, "proxy_user")), + WidgetEntry(N_("Proxy password:"), WidgetString(0, "proxy_pass"), {true})}; + +static const PreferencesWidget connectivity_page_widgets[] = { + WidgetLabel(N_("<b>Network Settings</b>")), + WidgetSpin(N_("Buffer size:"), WidgetInt(0, "net_buffer_kb"), + {16, 1024, 16, N_("KiB")}), + WidgetLabel(N_("<b>Proxy Configuration</b>")), + WidgetCheck(N_("Enable proxy usage"), WidgetBool(0, "use_proxy")), + WidgetTable({{proxy_host_port_elements}}, WIDGET_CHILD), + WidgetCheck(N_("Use authentication with proxy"), + WidgetBool(0, "use_proxy_auth")), + WidgetTable({{proxy_auth_elements}}, WIDGET_CHILD), + WidgetCheck(N_("Use SOCKS proxy"), WidgetBool(0, "socks_proxy")), + WidgetRadio(N_("SOCKS v4a"), WidgetInt(0, "socks_type"), {0}, WIDGET_CHILD), + WidgetRadio(N_("SOCKS v5"), WidgetInt(0, "socks_type"), {1}, WIDGET_CHILD)}; + +static const PreferencesWidget chardet_elements[] = { + WidgetCombo(N_("Auto character encoding detector for:"), + WidgetString(0, "chardet_detector"), + {{chardet_detector_presets}}), + WidgetEntry(N_("Fallback character encodings:"), + WidgetString(0, "chardet_fallback"))}; + +static void send_title_change(); +static void * create_titlestring_table(); + +static const PreferencesWidget playlist_page_widgets[] = { + WidgetLabel(N_("<b>Behavior</b>")), + WidgetCheck(N_("Resume playback on startup"), + WidgetBool(0, "resume_playback_on_startup")), + WidgetCheck(N_("Pause instead of resuming immediately"), + WidgetBool(0, "always_resume_paused"), WIDGET_CHILD), + WidgetCheck(N_("Advance when the current song is deleted"), + WidgetBool(0, "advance_on_delete")), + WidgetCheck(N_("Clear the playlist when opening files"), + WidgetBool(0, "clear_playlist")), + WidgetCheck(N_("Open files in a temporary playlist"), + WidgetBool(0, "open_to_temporary")), + WidgetLabel(N_("<b>Song Display</b>")), + WidgetCheck(N_("Show song numbers"), + WidgetBool(0, "show_numbers_in_pl", send_title_change)), + WidgetCheck(N_("Show leading zeroes (02:00 vs. 2:00)"), + WidgetBool(0, "leading_zero", send_title_change)), + WidgetCheck(N_("Show hours separately (1:30:00 vs. 90:00)"), + WidgetBool(0, "show_hours", send_title_change)), + WidgetCustomQt(create_titlestring_table), + WidgetLabel(N_("<b>Export</b>")), + WidgetCheck(N_("Use relative paths when possible"), + WidgetBool(0, "export_relative_paths"))}; + +static const PreferencesWidget song_info_page_widgets[] = { + WidgetLabel(N_("<b>Album Art</b>")), + WidgetLabel( + N_("Search for images matching these words (comma-separated):")), + WidgetEntry(0, WidgetString(0, "cover_name_include")), + WidgetLabel(N_("Exclude images matching these words (comma-separated):")), + WidgetEntry(0, WidgetString(0, "cover_name_exclude")), + WidgetCheck(N_("Search for images matching song file name"), + WidgetBool(0, "use_file_cover")), + WidgetCheck(N_("Search recursively"), WidgetBool(0, "recurse_for_cover")), + WidgetSpin(N_("Search depth:"), WidgetInt(0, "recurse_for_cover_depth"), + {0, 100, 1}, WIDGET_CHILD), + WidgetLabel(N_("<b>Popup Information</b>")), + WidgetCheck(N_("Show popup information"), + WidgetBool(0, "show_filepopup_for_tuple")), + WidgetSpin(N_("Popup delay (tenths of a second):"), + WidgetInt(0, "filepopup_delay"), {0, 100, 1}, WIDGET_CHILD)}; + +static const PreferencesWidget advanced_page_widgets[] = { + WidgetLabel(N_("<b>Compatibility</b>")), + WidgetCheck(N_("Interpret \\ (backward slash) as a folder delimiter"), + WidgetBool(0, "convert_backslash")), + WidgetTable({{chardet_elements}}), + WidgetLabel(N_("<b>Playlist</b>")), + WidgetCheck(N_("Add folders recursively"), + WidgetBool(0, "recurse_folders")), + WidgetCheck(N_("Add folders nested within playlist files"), + WidgetBool(0, "folders_in_playlist")), + WidgetLabel(N_("<b>Metadata</b>")), + WidgetCheck(N_("Guess missing metadata from file path"), + WidgetBool(0, "metadata_fallbacks")), + WidgetCheck(N_("Do not load metadata for songs until played"), + WidgetBool(0, "metadata_on_play")), + WidgetCheck( + N_("Probe content of files with no recognized file name extension"), + WidgetBool(0, "slow_probe")), + WidgetLabel(N_("<b>Miscellaneous</b>")), + WidgetSpin(N_("Step forward/backward by:"), WidgetInt(0, "step_size"), + {1, 60, 1, N_("seconds")}), + WidgetSpin(N_("Adjust volume by:"), WidgetInt(0, "volume_delta"), + {1, 25, 1, N_("percent")})}; + +#define TITLESTRING_NPRESETS 8 + +static const char * const titlestring_presets[TITLESTRING_NPRESETS] = { + "${title}", + "${title}${?artist: - ${artist}}", + "${title}${?artist: - ${artist}}${?album: - ${album}}", + "${?artist:${artist} - }${title}", + "${?artist:${artist} - }${?album:${album} - }${title}", + "${?artist:${artist} - }${?album:${album} - " + "}${?track-number:${track-number}. }${title}", + "${?artist:${artist} }${?album:[ ${album} ] }${?artist:- " + "}${?track-number:${track-number}. }${title}", + "${?album:${album} - }${title}"}; + +static const char * const titlestring_preset_names[TITLESTRING_NPRESETS] = { + N_("TITLE"), + N_("TITLE - ARTIST"), + N_("TITLE - ARTIST - ALBUM"), + N_("ARTIST - TITLE"), + N_("ARTIST - ALBUM - TITLE"), + N_("ARTIST - ALBUM - TRACK. TITLE"), + N_("ARTIST [ ALBUM ] - TRACK. TITLE"), + N_("ALBUM - TITLE")}; + +static void * create_titlestring_table() +{ + QWidget * w = new QWidget; + QGridLayout * l = new QGridLayout(w); + l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(sizes.TwoPt); + + QLabel * lbl = new QLabel(_("Title format:"), w); + l->addWidget(lbl, 0, 0); + + QComboBox * cbox = new QComboBox(w); + l->addWidget(cbox, 0, 1); + + for (int i = 0; i < TITLESTRING_NPRESETS; i++) + cbox->addItem(translate_str(titlestring_preset_names[i]), i); + cbox->addItem(_("Custom"), TITLESTRING_NPRESETS); + cbox->setCurrentIndex(TITLESTRING_NPRESETS); + + lbl = new QLabel(_("Custom string:"), w); + l->addWidget(lbl, 1, 0); + + QLineEdit * le = new QLineEdit(w); + l->addWidget(le, 1, 1); + + String format = aud_get_str("generic_title_format"); + le->setText((const char *)format); + for (int i = 0; i < TITLESTRING_NPRESETS; i++) + { + if (!strcmp(titlestring_presets[i], format)) + cbox->setCurrentIndex(i); + } + + QObject::connect(le, &QLineEdit::textChanged, [](const QString & text) { + aud_set_str("generic_title_format", text.toUtf8().data()); + }); + + void (QComboBox::*signal)(int) = &QComboBox::currentIndexChanged; + QObject::connect(cbox, signal, [le](int idx) { + if (idx < TITLESTRING_NPRESETS) + le->setText(titlestring_presets[idx]); + }); + + /* build menu */ + QPushButton * btn_mnu = new QPushButton(w); + btn_mnu->setFixedWidth(btn_mnu->sizeHint().height()); + btn_mnu->setIcon(audqt::get_icon("list-add")); + l->addWidget(btn_mnu, 1, 2); + + QMenu * mnu_fields = new QMenu(w); + + for (auto & t : title_field_tags) + { + QAction * a = mnu_fields->addAction(_(t.name)); + QObject::connect(a, &QAction::triggered, [=]() { le->insert(t.tag); }); + } + + QObject::connect(btn_mnu, &QAbstractButton::clicked, [=]() { + mnu_fields->popup(btn_mnu->mapToGlobal(QPoint(0, 0))); + }); + + return w; +} + +static Index<ComboItem> fill_plugin_combo(PluginType type) +{ + Index<ComboItem> elems; + int i = 0; + + for (PluginHandle * plugin : aud_plugin_list(type)) + elems.append(aud_plugin_get_name(plugin), i++); + + return elems; +} + +static void send_title_change() +{ + if (aud_drct_get_ready()) + hook_call("title change", nullptr); +} + +static void iface_fill_prefs_box() +{ + Plugin * header = (Plugin *)aud_plugin_get_header( + aud_plugin_get_current(PluginType::Iface)); + if (header && header->info.prefs) + { + auto vbox = make_vbox(iface_prefs_box, sizes.TwoPt); + prefs_populate(vbox, header->info.prefs->widgets, header->info.domain); + } +} + +static void iface_combo_changed() +{ + /* prevent audqt from being shut down during the switch */ + init(); + + if (QLayout * layout = iface_prefs_box->layout()) + { + clear_layout(layout); + delete layout; + } + + aud_plugin_enable(aud_plugin_list(PluginType::Iface)[iface_combo_selected], + true); + + iface_fill_prefs_box(); + cleanup(); +} + +static ArrayRef<ComboItem> iface_combo_fill() +{ + if (!iface_combo_elements.len()) + { + iface_combo_elements = fill_plugin_combo(PluginType::Iface); + iface_combo_selected = + aud_plugin_list(PluginType::Iface) + .find(aud_plugin_get_current(PluginType::Iface)); + } + + return {iface_combo_elements.begin(), iface_combo_elements.len()}; +} + +static void * iface_create_prefs_box() +{ + iface_prefs_box = new QWidget; + iface_fill_prefs_box(); + return iface_prefs_box; +} + +static void output_bit_depth_changed() +{ + aud_output_reset(OutputReset::ReopenStream); +} + +static void create_category(QStackedWidget * notebook, + ArrayRef<PreferencesWidget> widgets) +{ + QWidget * w = new QWidget; + auto vbox = make_vbox(w, sizes.TwoPt); + prefs_populate(vbox, widgets, nullptr); + vbox->addStretch(1); + + notebook->addWidget(w); +} + +static QTreeView * s_plugin_view; +static PluginListModel * s_plugin_model; + +static void create_plugin_category(QStackedWidget * parent) +{ + s_plugin_view = new QTreeView(parent); + s_plugin_model = new PluginListModel(s_plugin_view); + + s_plugin_view->setModel(s_plugin_model); + s_plugin_view->setSelectionMode(QTreeView::NoSelection); + s_plugin_view->setAlternatingRowColors(true); + + auto header = s_plugin_view->header(); + + header->hide(); + header->setSectionResizeMode(header->ResizeToContents); + header->setStretchLastSection(true); + + parent->addWidget(s_plugin_view); + + QObject::connect(s_plugin_view, &QAbstractItemView::clicked, + [](const QModelIndex & index) { + auto p = s_plugin_model->pluginForIndex(index); + if (!p || !aud_plugin_get_enabled(p)) + return; + + switch (index.column()) + { + case PluginListModel::AboutColumn: + plugin_about(p); + break; + case PluginListModel::SettingsColumn: + plugin_prefs(p); + break; + } + }); +} + +static QStackedWidget * s_category_notebook = nullptr; + +PrefsWindow::PrefsWindow() + : output_combo_elements(fill_plugin_combo(PluginType::Output)), + output_config_button(new QPushButton(translate_str(N_("_Settings")))), + output_about_button(new QPushButton(translate_str(N_("_About")))), + record_checkbox(new QCheckBox), + record_config_button(new QPushButton(translate_str(N_("_Settings")))), + record_about_button(new QPushButton(translate_str(N_("_About")))) +{ + /* initialize static data */ + instance = this; + output_combo_selected = + aud_plugin_list(PluginType::Output) + .find(aud_plugin_get_current(PluginType::Output)); + + setAttribute(Qt::WA_DeleteOnClose); + setWindowTitle(_("Audacious Settings")); + setContentsMargins(0, 0, 0, 0); + + output_config_button->setAutoDefault(false); + output_about_button->setAutoDefault(false); + record_config_button->setAutoDefault(false); + record_about_button->setAutoDefault(false); + + QToolBar * toolbar = new QToolBar; + toolbar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + + QWidget * child = new QWidget; + child->setContentsMargins(margins.FourPt); + + auto vbox_parent = make_vbox(this); + vbox_parent->addWidget(toolbar); + vbox_parent->addWidget(child); + + auto child_vbox = make_vbox(child); + + s_category_notebook = new QStackedWidget; + child_vbox->addWidget(s_category_notebook); + + create_category(s_category_notebook, appearance_page_widgets); + create_category(s_category_notebook, audio_page_widgets); + create_category(s_category_notebook, connectivity_page_widgets); + create_category(s_category_notebook, playlist_page_widgets); + create_category(s_category_notebook, song_info_page_widgets); + create_plugin_category(s_category_notebook); + create_category(s_category_notebook, advanced_page_widgets); + + QDialogButtonBox * bbox = new QDialogButtonBox(QDialogButtonBox::Close); + bbox->button(QDialogButtonBox::Close)->setText(translate_str(N_("_Close"))); + child_vbox->addWidget(bbox); + + QObject::connect(bbox, &QDialogButtonBox::rejected, this, + &QObject::deleteLater); + + for (int i = 0; i < CATEGORY_COUNT; i++) + { + auto a = new QAction(get_icon(categories[i].icon), + translate_str(categories[i].name), toolbar); + + toolbar->addAction(a); + + connect(a, &QAction::triggered, + [i]() { s_category_notebook->setCurrentIndex(i); }); + } + + output_setup(); + record_setup(); + record_update(); +} + +void PrefsWindow::output_setup() +{ + auto p = aud_plugin_get_current(PluginType::Output); + + output_config_button->setEnabled(aud_plugin_has_configure(p)); + output_about_button->setEnabled(aud_plugin_has_about(p)); + + QObject::connect(output_config_button, &QPushButton::clicked, [](bool) { + plugin_prefs(aud_plugin_get_current(PluginType::Output)); + }); + + QObject::connect(output_about_button, &QPushButton::clicked, [](bool) { + plugin_about(aud_plugin_get_current(PluginType::Output)); + }); +} + +void PrefsWindow::output_change() +{ + auto & list = aud_plugin_list(PluginType::Output); + auto p = list[output_combo_selected]; + + if (aud_plugin_enable(p, true)) + { + output_config_button->setEnabled(aud_plugin_has_configure(p)); + output_about_button->setEnabled(aud_plugin_has_about(p)); + } + else + { + /* set combo box back to current output */ + output_combo_selected = + list.find(aud_plugin_get_current(PluginType::Output)); + hook_call("audqt update output combo", nullptr); + } +} + +void PrefsWindow::record_setup() +{ + QObject::connect(record_checkbox, &QCheckBox::clicked, + [](bool checked) { aud_drct_enable_record(checked); }); + + QObject::connect(record_config_button, &QPushButton::clicked, [](bool) { + if (aud_drct_get_record_enabled()) + plugin_prefs(aud_drct_get_record_plugin()); + }); + + QObject::connect(record_about_button, &QPushButton::clicked, [](bool) { + if (aud_drct_get_record_enabled()) + plugin_about(aud_drct_get_record_plugin()); + }); +} + +void PrefsWindow::record_update() +{ + auto p = aud_drct_get_record_plugin(); + + if (p) + { + bool enabled = aud_drct_get_record_enabled(); + auto text = str_printf(_("Enable audio stream recording with %s"), + aud_plugin_get_name(p)); + + record_checkbox->setEnabled(true); + record_checkbox->setText((const char *)text); + record_checkbox->setChecked(enabled); + record_config_button->setEnabled(enabled && + aud_plugin_has_configure(p)); + record_about_button->setEnabled(enabled && aud_plugin_has_about(p)); + } + else + { + record_checkbox->setEnabled(false); + record_checkbox->setText(_("No audio recording plugin available")); + record_checkbox->setChecked(false); + record_config_button->setEnabled(false); + record_about_button->setEnabled(false); + } +} + +EXPORT void prefswin_show() +{ + window_bring_to_front(PrefsWindow::get_instance()); +} + +EXPORT void prefswin_hide() { PrefsWindow::destroy_instance(); } + +EXPORT void prefswin_show_page(int id, bool show) +{ + if (id < 0 || id > CATEGORY_COUNT) + return; + + auto win = PrefsWindow::get_instance(); + s_category_notebook->setCurrentIndex(id); + + if (show) + window_bring_to_front(win); +} + +EXPORT void prefswin_show_plugin_page(PluginType type) +{ + if (type == PluginType::Iface) + prefswin_show_page(CATEGORY_APPEARANCE); + else if (type == PluginType::Output) + prefswin_show_page(CATEGORY_AUDIO); + else + { + prefswin_show_page(CATEGORY_PLUGINS, false); + + s_plugin_view->collapseAll(); + + auto index = s_plugin_model->indexForType(type); + if (index.isValid()) + { + s_plugin_view->expand(index); + s_plugin_view->scrollTo(index, QTreeView::PositionAtTop); + s_plugin_view->setCurrentIndex(index); + } + + window_bring_to_front(PrefsWindow::get_instance()); + } +} + +} // namespace audqt diff --git a/src/libaudqt/queue-manager-qt.cc b/src/libaudqt/queue-manager-qt.cc new file mode 100644 index 0000000..dd1e993 --- /dev/null +++ b/src/libaudqt/queue-manager-qt.cc @@ -0,0 +1,229 @@ +/* + * queue-manager.cc + * Copyright 2014 Ariadne Conill, John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt.h" + +#include <QAbstractListModel> +#include <QDialog> +#include <QDialogButtonBox> +#include <QHeaderView> +#include <QItemSelectionModel> +#include <QPointer> +#include <QPushButton> +#include <QTreeView> +#include <QVBoxLayout> + +#include <libaudcore/audstrings.h> +#include <libaudcore/hook.h> +#include <libaudcore/i18n.h> +#include <libaudcore/playlist.h> + +/* + * TODO: + * - shifting of selection entries + */ + +namespace audqt +{ + +class QueueManagerModel : public QAbstractListModel +{ +public: + void update(QItemSelectionModel * sel); + void selectionChanged(const QItemSelection & selected, + const QItemSelection & deselected); + +protected: + int rowCount(const QModelIndex & parent) const + { + return parent.isValid() ? 0 : m_rows; + } + + int columnCount(const QModelIndex & parent) const { return 2; } + QVariant data(const QModelIndex & index, int role) const; + +private: + int m_rows = 0; + bool m_in_update = false; +}; + +QVariant QueueManagerModel::data(const QModelIndex & index, int role) const +{ + if (role == Qt::DisplayRole) + { + auto list = Playlist::active_playlist(); + int entry = list.queue_get_entry(index.row()); + + if (index.column() == 0) + return entry + 1; + else + { + Tuple tuple = list.entry_tuple(entry, Playlist::NoWait); + return QString((const char *)tuple.get_str(Tuple::FormattedTitle)); + } + } + else if (role == Qt::TextAlignmentRole && index.column() == 0) + return Qt::AlignRight; + + return QVariant(); +} + +void QueueManagerModel::update(QItemSelectionModel * sel) +{ + auto list = Playlist::active_playlist(); + int rows = list.n_queued(); + int keep = aud::min(rows, m_rows); + + m_in_update = true; + + if (rows < m_rows) + { + beginRemoveRows(QModelIndex(), rows, m_rows - 1); + m_rows = rows; + endRemoveRows(); + } + else if (rows > m_rows) + { + beginInsertRows(QModelIndex(), m_rows, rows - 1); + m_rows = rows; + endInsertRows(); + } + + if (keep > 0) + { + auto topLeft = createIndex(0, 0); + auto bottomRight = createIndex(keep - 1, 0); + emit dataChanged(topLeft, bottomRight); + } + + for (int i = 0; i < rows; i++) + { + if (list.entry_selected(list.queue_get_entry(i))) + sel->select(createIndex(i, 0), sel->Select | sel->Rows); + else + sel->select(createIndex(i, 0), sel->Deselect | sel->Rows); + } + + m_in_update = false; +} + +void QueueManagerModel::selectionChanged(const QItemSelection & selected, + const QItemSelection & deselected) +{ + if (m_in_update) + return; + + auto list = Playlist::active_playlist(); + + for (auto & index : selected.indexes()) + list.select_entry(list.queue_get_entry(index.row()), true); + + for (auto & index : deselected.indexes()) + list.select_entry(list.queue_get_entry(index.row()), false); +} + +class QueueManagerDialog : public QDialog +{ +public: + QueueManagerDialog(QWidget * parent = nullptr); + +private: + QTreeView m_treeview; + QDialogButtonBox m_buttonbox; + QPushButton m_btn_unqueue; + QPushButton m_btn_close; + QueueManagerModel m_model; + + void removeSelected(); + void update() { m_model.update(m_treeview.selectionModel()); } + + const HookReceiver<QueueManagerDialog> update_hook{ + "playlist update", this, &QueueManagerDialog::update}, + activate_hook{"playlist activate", this, &QueueManagerDialog::update}; +}; + +QueueManagerDialog::QueueManagerDialog(QWidget * parent) : QDialog(parent) +{ + setWindowTitle(_("Queue Manager")); + setContentsMargins(margins.TwoPt); + + m_btn_unqueue.setText(translate_str(N_("_Unqueue"))); + m_btn_close.setText(translate_str(N_("_Close"))); + + connect(&m_btn_close, &QAbstractButton::clicked, this, &QWidget::hide); + connect(&m_btn_unqueue, &QAbstractButton::clicked, this, + &QueueManagerDialog::removeSelected); + + m_buttonbox.addButton(&m_btn_close, QDialogButtonBox::AcceptRole); + m_buttonbox.addButton(&m_btn_unqueue, QDialogButtonBox::AcceptRole); + + auto layout = make_vbox(this); + layout->addWidget(&m_treeview); + layout->addWidget(&m_buttonbox); + + m_treeview.setAllColumnsShowFocus(true); + m_treeview.setIndentation(0); + m_treeview.setModel(&m_model); + m_treeview.setSelectionMode(QAbstractItemView::ExtendedSelection); + m_treeview.setHeaderHidden(true); + + update(); + + connect(m_treeview.selectionModel(), &QItemSelectionModel::selectionChanged, + &m_model, &QueueManagerModel::selectionChanged); + + resize(4 * sizes.OneInch, 3 * sizes.OneInch); +} + +void QueueManagerDialog::removeSelected() +{ + auto list = Playlist::active_playlist(); + int count = list.n_queued(); + + for (int i = 0; i < count;) + { + int entry = list.queue_get_entry(i); + + if (list.entry_selected(entry)) + { + list.queue_remove(i); + list.select_entry(entry, false); + count--; + } + else + i++; + } +} + +static QPointer<QueueManagerDialog> s_queuemgr; + +EXPORT void queue_manager_show() +{ + if (!s_queuemgr) + { + s_queuemgr = new QueueManagerDialog; + s_queuemgr->setAttribute(Qt::WA_DeleteOnClose); + } + + window_bring_to_front(s_queuemgr); +} + +EXPORT void queue_manager_hide() { delete s_queuemgr; } + +} // namespace audqt diff --git a/src/libaudqt/treeview.cc b/src/libaudqt/treeview.cc new file mode 100644 index 0000000..add19ab --- /dev/null +++ b/src/libaudqt/treeview.cc @@ -0,0 +1,123 @@ +/* + * treeview.cc + * Copyright 2018 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "treeview.h" + +#include <QApplication> +#include <QKeyEvent> +#include <QMouseEvent> +#include <QProxyStyle> + +#include <libaudcore/index.h> + +namespace audqt +{ + +/* + * On some platforms (mainly KDE), there is a feature where + * clicking on icons makes them work like hyperlinks. Unfortunately, + * the way this is implemented is by making all QAbstractItemView + * widgets behave in this way. + * + * In all situations, it makes no sense for audqt::TreeView + * widgets to behave in this way. So we override that feature + * with a QProxyStyle. + */ +class TreeViewStyleOverrides : public QProxyStyle +{ +public: + TreeViewStyleOverrides() + { + // detect and respond to application-wide style change + connect(qApp->style(), &QObject::destroyed, this, + &TreeViewStyleOverrides::resetBaseStyle); + } + + int styleHint(StyleHint hint, const QStyleOption * option = nullptr, + const QWidget * widget = nullptr, + QStyleHintReturn * returnData = nullptr) const override + { + if (hint == QStyle::SH_ItemView_ActivateItemOnSingleClick) + return 0; + + return QProxyStyle::styleHint(hint, option, widget, returnData); + } + +private: + void resetBaseStyle() + { + setBaseStyle(nullptr); + connect(qApp->style(), &QObject::destroyed, this, + &TreeViewStyleOverrides::resetBaseStyle); + } +}; + +EXPORT TreeView::TreeView(QWidget * parent) : QTreeView(parent) +{ + auto style = new TreeViewStyleOverrides; + style->setParent(this); + setStyle(style); + + // activate() is perhaps a bit redundant with activated() + connect(this, &QTreeView::activated, this, &TreeView::activate); +} + +EXPORT TreeView::~TreeView() {} + +EXPORT void TreeView::keyPressEvent(QKeyEvent * event) +{ + auto CtrlShiftAlt = + Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier; + if (event->key() == Qt::Key_Delete && !(event->modifiers() & CtrlShiftAlt)) + { + removeSelectedRows(); + return; + } + + QTreeView::keyPressEvent(event); +} + +EXPORT void TreeView::removeSelectedRows() +{ + // get all selected rows + Index<int> rows; + for (auto & idx : selectionModel()->selectedRows()) + rows.append(idx.row()); + + // sort in reverse order + rows.sort([](const int & a, const int & b) { return b - a; }); + + // remove rows in reverse order + auto m = model(); + for (int row : rows) + m->removeRow(row); +} + +// TODO: unnecessary, remove at next API break +EXPORT void TreeView::mouseDoubleClickEvent(QMouseEvent * event) +{ + QTreeView::mouseDoubleClickEvent(event); +} + +EXPORT void TreeView::activate(const QModelIndex & index) +{ + (void)index; // base implementation does nothing +} + +} // namespace audqt diff --git a/src/libaudqt/treeview.h b/src/libaudqt/treeview.h new file mode 100644 index 0000000..565af04 --- /dev/null +++ b/src/libaudqt/treeview.h @@ -0,0 +1,49 @@ +/* + * treeview.h + * Copyright 2018 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef LIBAUDQT_TREEVIEW_H +#define LIBAUDQT_TREEVIEW_H + +#include <QTreeView> +#include <libaudqt/export.h> + +namespace audqt +{ + +// This class extends QTreeView and adds a couple of features: +// - An "activate" event (double click or Enter key) +// - A method to remove all selected rows (Delete key) +class LIBAUDQT_PUBLIC TreeView : public QTreeView +{ +public: + TreeView(QWidget * parent = nullptr); + ~TreeView() override; + + void removeSelectedRows(); + +protected: + void keyPressEvent(QKeyEvent * event) override; + void mouseDoubleClickEvent(QMouseEvent * event) override; + + virtual void activate(const QModelIndex & index); +}; + +} // namespace audqt + +#endif // LIBAUDQT_TREEVIEW_H diff --git a/src/libaudqt/url-opener-qt.cc b/src/libaudqt/url-opener-qt.cc new file mode 100644 index 0000000..1542142 --- /dev/null +++ b/src/libaudqt/url-opener-qt.cc @@ -0,0 +1,143 @@ +/* + * url-opener.cc + * Copyright 2015 Thomas Lange + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <QComboBox> +#include <QDialog> +#include <QDialogButtonBox> +#include <QLabel> +#include <QPointer> +#include <QPushButton> +#include <QVBoxLayout> + +#include <libaudcore/drct.h> +#include <libaudcore/i18n.h> +#include <libaudcore/preferences.h> +#include <libaudcore/runtime.h> + +#include "libaudqt.h" + +namespace audqt +{ + +static QDialog * buildUrlDialog(bool open) +{ + static const PreferencesWidget widgets[] = { + WidgetCheck(N_("_Save to history"), WidgetBool(0, "save_url_history"))}; + + const char *title, *verb, *icon; + + if (open) + { + title = _("Open URL"); + verb = _("_Open"); + icon = "document-open"; + } + else + { + title = _("Add URL"); + verb = _("_Add"); + icon = "list-add"; + } + + auto dialog = new QDialog; + dialog->setWindowTitle(title); + dialog->setContentsMargins(margins.EightPt); + + auto label = new QLabel(_("Enter URL:"), dialog); + + auto combobox = new QComboBox(dialog); + combobox->setEditable(true); + combobox->setMinimumContentsLength(50); + + auto clear_button = + new QPushButton(translate_str(N_("C_lear history")), dialog); + clear_button->setIcon(audqt::get_icon("edit-clear")); + + auto hbox = make_hbox(nullptr); + prefs_populate(hbox, widgets, PACKAGE); + hbox->addStretch(1); + hbox->addWidget(clear_button); + + auto button1 = new QPushButton(translate_str(verb), dialog); + button1->setIcon(audqt::get_icon(icon)); + + auto button2 = new QPushButton(translate_str(N_("_Cancel")), dialog); + button2->setIcon(audqt::get_icon("process-stop")); + + auto buttonbox = new QDialogButtonBox(dialog); + buttonbox->addButton(button1, QDialogButtonBox::AcceptRole); + buttonbox->addButton(button2, QDialogButtonBox::RejectRole); + + auto layout = make_vbox(dialog); + layout->addWidget(label); + layout->addWidget(combobox); + layout->addLayout(hbox); + layout->addStretch(1); + layout->addWidget(buttonbox); + + for (int i = 0;; i++) + { + String item = aud_history_get(i); + if (!item) + break; + + combobox->addItem(QString(item)); + } + combobox->setCurrentIndex(-1); + + QObject::connect(clear_button, &QPushButton::pressed, [combobox]() { + combobox->clear(); + aud_history_clear(); + }); + + QObject::connect(buttonbox, &QDialogButtonBox::rejected, dialog, + &QDialog::close); + + QObject::connect(buttonbox, &QDialogButtonBox::accepted, + [dialog, combobox, open]() { + QByteArray url = combobox->currentText().toUtf8(); + + if (open) + aud_drct_pl_open(url); + else + aud_drct_pl_add(url, -1); + + if (aud_get_bool("save_url_history")) + aud_history_add(url); + + dialog->close(); + }); + + return dialog; +} + +static QPointer<QDialog> s_dialog; + +EXPORT void urlopener_show(bool open) +{ + if (!s_dialog) + { + s_dialog = buildUrlDialog(open); + s_dialog->setAttribute(Qt::WA_DeleteOnClose); + } + + window_bring_to_front(s_dialog); +} + +} // namespace audqt diff --git a/src/libaudqt/util-qt.cc b/src/libaudqt/util-qt.cc new file mode 100644 index 0000000..9cc427a --- /dev/null +++ b/src/libaudqt/util-qt.cc @@ -0,0 +1,125 @@ +/* + * util-qt.cc + * Copyright 2017 René Bertin and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt-internal.h" +#include "libaudqt.h" + +#include <QAction> +#include <QApplication> +#include <QClipboard> +#include <QCursor> +#include <QMenu> +#include <QMimeData> +#include <QScreen> +#include <QWindow> + +#include <libaudcore/i18n.h> + +namespace audqt +{ + +PopupWidget::PopupWidget(QWidget * parent) : QWidget(parent) +{ + qApp->installEventFilter(this); +} + +// This event filter mimics QToolTip by hiding the popup widget when +// certain events are received by any widget. +bool PopupWidget::eventFilter(QObject *, QEvent * e) +{ + switch (e->type()) + { + case QEvent::Leave: + case QEvent::WindowActivate: + case QEvent::WindowDeactivate: + case QEvent::FocusIn: + case QEvent::FocusOut: + case QEvent::Close: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::Wheel: + deleteLater(); + break; + + default: + break; + } + + return false; +} + +void PopupWidget::showEvent(QShowEvent *) +{ + auto pos = QCursor::pos(); + auto geom = QApplication::primaryScreen()->geometry(); + + /* find the screen the cursor is on */ + if (!geom.contains(pos)) + { + for (auto screen : QApplication::screens()) + { + auto geom2 = screen->geometry(); + if (geom2.contains(pos)) + { + geom = geom2; + break; + } + } + } + + int x = pos.x(); + int y = pos.y(); + int w = width(); + int h = height(); + + /* If we show the popup right under the cursor, the underlying window gets + * a leaveEvent and immediately hides the popup again. So, we offset the + * popup slightly. */ + if (x + w > geom.x() + geom.width()) + x -= w + 3; + else + x += 3; + + if (y + h > geom.y() + geom.height()) + y -= h + 3; + else + y += 3; + + move(x, y); +} + +void show_copy_context_menu(QWidget * parent, const QPoint & global_pos, + const QString & text_to_copy) +{ + auto menu = new QMenu(parent); + auto action = new QAction(audqt::get_icon("edit-copy"), N_("Copy"), menu); + + QObject::connect(action, &QAction::triggered, action, [text_to_copy]() { + auto data = new QMimeData; + data->setText(text_to_copy); + QApplication::clipboard()->setMimeData(data); + }); + + menu->addAction(action); + menu->setAttribute(Qt::WA_DeleteOnClose); + menu->popup(global_pos); +} + +} // namespace audqt diff --git a/src/libaudqt/volumebutton.cc b/src/libaudqt/volumebutton.cc new file mode 100644 index 0000000..8e6c5d9 --- /dev/null +++ b/src/libaudqt/volumebutton.cc @@ -0,0 +1,188 @@ +/* + * volumebutton.cc + * Copyright 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "libaudqt.h" + +#include <QFrame> +#include <QIcon> +#include <QSlider> +#include <QToolButton> +#include <QVBoxLayout> +#include <QWheelEvent> + +#include <libaudcore/drct.h> +#include <libaudcore/hook.h> +#include <libaudcore/runtime.h> + +namespace audqt +{ + +class VolumeButton : public QToolButton +{ +public: + VolumeButton(QWidget * parent = nullptr); + +private: + void updateDelta(); + void updateIcon(int val); + void updateVolume(); + void showSlider(); + void setVolume(int val); + QToolButton * newSliderButton(int dir); + + void wheelEvent(QWheelEvent * e); + + QSlider * m_slider; + QFrame * m_container; + int m_scroll_delta = 0; + + HookReceiver<VolumeButton> update_hook{"set volume_delta", this, + &VolumeButton::updateDelta}; +}; + +VolumeButton::VolumeButton(QWidget * parent) : QToolButton(parent) +{ + setFocusPolicy(Qt::NoFocus); + + m_container = new QFrame(this, Qt::Popup); + m_container->setFrameShape(QFrame::StyledPanel); + + m_slider = new QSlider(Qt::Vertical, this); + m_slider->setMinimumHeight(audqt::sizes.OneInch); + m_slider->setRange(0, 100); + + updateDelta(); + + auto layout = make_vbox(m_container, sizes.TwoPt); + layout->setContentsMargins(margins.TwoPt); + + layout->addWidget(newSliderButton(1)); + layout->addWidget(m_slider); + layout->addWidget(newSliderButton(-1)); + + int val = aud_drct_get_volume_main(); + m_slider->setValue(val); + updateIcon(val); + + connect(this, &QAbstractButton::clicked, this, &VolumeButton::showSlider); + connect(m_slider, &QAbstractSlider::valueChanged, this, + &VolumeButton::setVolume); + + auto timer = new Timer<VolumeButton>(TimerRate::Hz4, this, + &VolumeButton::updateVolume); + connect(this, &QObject::destroyed, [timer]() { delete timer; }); + + timer->start(); +} + +void VolumeButton::updateDelta() +{ + int delta = aud_get_int("volume_delta"); + m_slider->setSingleStep(delta); + m_slider->setPageStep(delta); +} + +void VolumeButton::updateIcon(int val) +{ + if (val == 0) + setIcon(audqt::get_icon("audio-volume-muted")); + else if (val < 34) + setIcon(audqt::get_icon("audio-volume-low")); + else if (val < 67) + setIcon(audqt::get_icon("audio-volume-medium")); + else + setIcon(audqt::get_icon("audio-volume-high")); + + setToolTip(QString("%1 %").arg(val)); +} + +void VolumeButton::updateVolume() +{ + if (m_slider->isSliderDown()) + return; + + int val = aud_drct_get_volume_main(); + if (val != m_slider->value()) + { + disconnect(m_slider, nullptr, this, nullptr); + m_slider->setValue(val); + updateIcon(val); + connect(m_slider, &QAbstractSlider::valueChanged, this, + &VolumeButton::setVolume); + } +} + +void VolumeButton::showSlider() +{ + QSize button_size = sizeHint(); + QSize container_size = m_container->sizeHint(); + + int dx = container_size.width() / 2 - button_size.width() / 2; + int dy = container_size.height() / 2 - button_size.height() / 2; + + QPoint pos = mapToGlobal(QPoint(0, 0)); + pos -= QPoint(dx, dy); + pos.setX(qMax(pos.x(), 0)); + pos.setY(qMax(pos.y(), 0)); + + m_container->move(pos); + window_bring_to_front(m_container); +} + +void VolumeButton::setVolume(int val) +{ + aud_drct_set_volume_main(val); + updateIcon(val); +} + +QToolButton * VolumeButton::newSliderButton(int dir) +{ + auto button = new QToolButton(this); + button->setText(dir < 0 ? "-" : "+"); + button->setAutoRaise(true); + button->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); + + connect(button, &QAbstractButton::clicked, [this, dir]() { + m_slider->setValue(m_slider->value() + + dir * aud_get_int("volume_delta")); + }); + + return button; +} + +void VolumeButton::wheelEvent(QWheelEvent * e) +{ + m_scroll_delta += e->angleDelta().y(); + + /* we want discrete steps here */ + int steps = m_scroll_delta / 120; + if (steps != 0) + { + m_scroll_delta -= 120 * steps; + m_slider->setValue(m_slider->value() + + steps * aud_get_int("volume_delta")); + } +} + +EXPORT QToolButton * volume_button_new(QWidget * parent) +{ + return new VolumeButton(parent); +} + +} // namespace audqt diff --git a/src/libaudtag/Makefile b/src/libaudtag/Makefile new file mode 100644 index 0000000..e11d814 --- /dev/null +++ b/src/libaudtag/Makefile @@ -0,0 +1,31 @@ +SHARED_LIB = ${LIB_PREFIX}audtag${LIB_SUFFIX} +LIB_MAJOR = 3 +LIB_MINOR = 0 + +SRCS = audtag.cc \ + util.cc \ + tag_module.cc \ + id3/id3-common.cc \ + id3/id3v1.cc \ + id3/id3v22.cc \ + id3/id3v24.cc \ + ape/ape.cc + +INCLUDES = audtag.h + +include ../../buildsys.mk +include ../../extra.mk + +LD = ${CXX} + +CPPFLAGS := -I.. -I../.. \ + ${CPPFLAGS} \ + ${GLIB_CFLAGS} + +CFLAGS += ${LIB_CFLAGS} + +LIB_LDFLAGS := -L../libaudcore $(LIB_LDFLAGS) + +LIBS := -laudcore \ + ${LIBS} \ + ${GLIB_LIBS} diff --git a/src/libaudtag/ape/ape.cc b/src/libaudtag/ape/ape.cc new file mode 100644 index 0000000..b94019e --- /dev/null +++ b/src/libaudtag/ape/ape.cc @@ -0,0 +1,419 @@ +/* + * ape.c + * Copyright 2010 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +/* TODO: + * - Support updating files that have their tag at the beginning? + */ + +#include <stdlib.h> +#include <string.h> + +#define WANT_AUD_BSWAP +#include <libaudcore/audio.h> +#include <libaudcore/audstrings.h> +#include <libaudcore/runtime.h> +#include <libaudcore/vfs.h> +#include <libaudtag/builtin.h> + +#pragma pack(push) /* must be byte-aligned */ +#pragma pack(1) +struct APEHeader { + char magic[8]; + uint32_t version; /* LE */ + uint32_t length; /* LE */ + uint32_t items; /* LE */ + uint32_t flags; /* LE */ + uint64_t reserved; +}; +#pragma pack(pop) + +struct ValuePair { + String key; + Index<char> value; +}; + +#define APE_FLAG_HAS_HEADER (1 << 31) +#define APE_FLAG_HAS_NO_FOOTER (1 << 30) +#define APE_FLAG_IS_HEADER (1 << 29) + +namespace audtag { + +static bool ape_read_header (VFSFile & handle, APEHeader * header) +{ + if (handle.fread (header, 1, sizeof (APEHeader)) != sizeof (APEHeader)) + return false; + + if (strncmp (header->magic, "APETAGEX", 8)) + return false; + + header->version = FROM_LE32 (header->version); + header->length = FROM_LE32 (header->length); + header->items = FROM_LE32 (header->items); + header->flags = FROM_LE32 (header->flags); + + if (header->length < sizeof (APEHeader)) + return false; + + return true; +} + +static bool ape_find_header (VFSFile & handle, APEHeader * header, + int * start, int * length, int * data_start, int * data_length) +{ + APEHeader secondary; + + if (handle.fseek (0, VFS_SEEK_SET)) + return false; + + if (ape_read_header (handle, header)) + { + AUDDBG ("Found header at 0, length = %d, version = %d.\n", + (int) header->length, (int) header->version); + + * start = 0; + * length = header->length; + * data_start = sizeof (APEHeader); + * data_length = header->length - sizeof (APEHeader); + + if (! (header->flags & APE_FLAG_HAS_HEADER) || ! (header->flags & APE_FLAG_IS_HEADER)) + { + AUDWARN ("Invalid header flags (%u).\n", (unsigned) header->flags); + return false; + } + + if (! (header->flags & APE_FLAG_HAS_NO_FOOTER)) + { + if (handle.fseek (header->length, VFS_SEEK_CUR)) + return false; + + if (! ape_read_header (handle, & secondary)) + { + AUDWARN ("Expected footer, but found none.\n"); + return false; + } + + * length += sizeof (APEHeader); + } + + return true; + } + + if (handle.fseek (-(int) sizeof (APEHeader), VFS_SEEK_END)) + return false; + + if (! ape_read_header (handle, header)) + { + /* APE tag may be followed by an ID3v1 tag */ + if (handle.fseek (-128 - (int) sizeof (APEHeader), VFS_SEEK_END)) + return false; + + if (! ape_read_header (handle, header)) + { + AUDDBG ("No header found.\n"); + return false; + } + } + + AUDDBG ("Found footer at %d, length = %d, version = %d.\n", + (int) handle.ftell () - (int) sizeof (APEHeader), (int) header->length, + (int) header->version); + + * start = handle.ftell () - header->length; + * length = header->length; + * data_start = handle.ftell () - header->length; + * data_length = header->length - sizeof (APEHeader); + + if ((header->flags & APE_FLAG_HAS_NO_FOOTER) || (header->flags & APE_FLAG_IS_HEADER)) + { + AUDWARN ("Invalid footer flags (%u).\n", (unsigned) header->flags); + return false; + } + + if (header->flags & APE_FLAG_HAS_HEADER) + { + if (handle.fseek (-(int) header->length - sizeof (APEHeader), VFS_SEEK_CUR)) + return false; + + if (! ape_read_header (handle, & secondary)) + { + AUDDBG ("Expected header, but found none.\n"); + return false; + } + + * start -= sizeof (APEHeader); + * length += sizeof (APEHeader); + } + + return true; +} + +bool APETagModule::can_handle_file (VFSFile & handle) +{ + APEHeader header; + int start, length, data_start, data_length; + + return ape_find_header (handle, & header, & start, & length, & data_start, + & data_length); +} + +/* returns start of next item or nullptr */ +static const char * ape_read_item (const char * data, int length, ValuePair & pair) +{ + auto header = (const uint32_t *) data; + const char * value; + + if (length < 8) + { + AUDWARN ("Expected item, but only %d bytes remain in tag.\n", length); + return nullptr; + } + + value = (const char *) memchr (data + 8, 0, length - 8); + + if (! value) + { + AUDWARN ("Unterminated item key (max length = %d).\n", length - 8); + return nullptr; + } + + value ++; + + uint32_t value_len = FROM_LE32 (header[0]); + if (value_len > (unsigned) (data + length - value)) + { + AUDWARN ("Item value of length %d, but only %d bytes remain in tag.\n", + (int) value_len, (int) (data + length - value)); + return nullptr; + } + + pair.key = String (data + 8); + pair.value.insert (value, -1, value_len); + pair.value.append (0); + + return value + value_len; +} + +static Index<ValuePair> ape_read_items (VFSFile & handle) +{ + Index<ValuePair> list; + APEHeader header; + int start, length, data_start, data_length; + + if (! ape_find_header (handle, & header, & start, & length, & data_start, & data_length)) + return list; + + if (handle.fseek (data_start, VFS_SEEK_SET)) + return list; + + Index<char> data; + data.insert (0, data_length); + + if (handle.fread (data.begin (), 1, data_length) != data_length) + return list; + + AUDDBG ("Reading %d items:\n", header.items); + const char * item = data.begin (); + + while (header.items --) + { + ValuePair pair; + if (! (item = ape_read_item (item, data.end () - item, pair))) + break; + + AUDDBG ("Read: %s = %s.\n", (const char *) pair.key, pair.value.begin ()); + list.append (std::move (pair)); + } + + return list; +} + +bool APETagModule::read_tag (VFSFile & handle, Tuple & tuple, Index<char> * image) +{ + Index<ValuePair> list = ape_read_items (handle); + + for (const ValuePair & pair : list) + { + if (! strcmp_nocase (pair.key, "Artist")) + tuple.set_str (Tuple::Artist, pair.value.begin ()); + else if (! strcmp_nocase (pair.key, "Title")) + tuple.set_str (Tuple::Title, pair.value.begin ()); + else if (! strcmp_nocase (pair.key, "Album")) + tuple.set_str (Tuple::Album, pair.value.begin ()); + else if (! strcmp_nocase (pair.key, "Comment")) + tuple.set_str (Tuple::Comment, pair.value.begin ()); + else if (! strcmp_nocase (pair.key, "Genre")) + tuple.set_str (Tuple::Genre, pair.value.begin ()); + else if (! strcmp_nocase (pair.key, "Track")) + tuple.set_int (Tuple::Track, atoi (pair.value.begin ())); + else if (! strcmp_nocase (pair.key, "Year")) + tuple.set_int (Tuple::Year, atoi (pair.value.begin ())); + else if (! strcmp_nocase (pair.key, "REPLAYGAIN_TRACK_GAIN")) + tuple.set_gain (Tuple::TrackGain, Tuple::GainDivisor, pair.value.begin ()); + else if (! strcmp_nocase (pair.key, "REPLAYGAIN_TRACK_PEAK")) + tuple.set_gain (Tuple::TrackPeak, Tuple::PeakDivisor, pair.value.begin ()); + else if (! strcmp_nocase (pair.key, "REPLAYGAIN_ALBUM_GAIN")) + tuple.set_gain (Tuple::AlbumGain, Tuple::GainDivisor, pair.value.begin ()); + else if (! strcmp_nocase (pair.key, "REPLAYGAIN_ALBUM_PEAK")) + tuple.set_gain (Tuple::AlbumPeak, Tuple::PeakDivisor, pair.value.begin ()); + } + + return true; +} + +static bool ape_write_item (VFSFile & handle, const char * key, + const char * value, int * written_length) +{ + int key_len = strlen (key) + 1; + int value_len = strlen (value); + uint32_t header[2]; + + AUDDBG ("Write: %s = %s.\n", key, value); + + header[0] = TO_LE32 (value_len); + header[1] = 0; + + if (handle.fwrite (header, 1, 8) != 8) + return false; + + if (handle.fwrite (key, 1, key_len) != key_len) + return false; + + if (handle.fwrite (value, 1, value_len) != value_len) + return false; + + * written_length += 8 + key_len + value_len; + return true; +} + +static bool write_string_item (const Tuple & tuple, Tuple::Field field, + VFSFile & handle, const char * key, int * written_length, int * written_items) +{ + String value = tuple.get_str (field); + + if (! value) + return true; + + bool success = ape_write_item (handle, key, value, written_length); + + if (success) + (* written_items) ++; + + return success; +} + +static bool write_integer_item (const Tuple & tuple, Tuple::Field field, + VFSFile & handle, const char * key, int * written_length, int * written_items) +{ + int value = tuple.get_int (field); + + if (value <= 0) + return true; + + if (! ape_write_item (handle, key, int_to_str (value), written_length)) + return false; + + (* written_items) ++; + return true; +} + +static bool write_header (int data_length, int items, bool is_header, + VFSFile & handle) +{ + APEHeader header; + + memcpy (header.magic, "APETAGEX", 8); + header.version = TO_LE32 (2000); + header.length = TO_LE32 (data_length + sizeof (APEHeader)); + header.items = TO_LE32 (items); + header.flags = is_header ? TO_LE32 (APE_FLAG_HAS_HEADER | + APE_FLAG_IS_HEADER) : TO_LE32 (APE_FLAG_HAS_HEADER); + header.reserved = 0; + + return handle.fwrite (& header, 1, sizeof (APEHeader)) == sizeof (APEHeader); +} + +bool APETagModule::write_tag (VFSFile & handle, const Tuple & tuple) +{ + Index<ValuePair> list = ape_read_items (handle); + APEHeader header; + int start, length, data_start, data_length, items; + + if (ape_find_header (handle, & header, & start, & length, & data_start, & data_length)) + { + if (start + length != handle.fsize ()) + { + AUDERR ("Writing tags is only supported at end of file.\n"); + return false; + } + + if (handle.ftruncate (start)) + return false; + } + else + { + start = handle.fsize (); + + if (start < 0) + return false; + } + + if (handle.fseek (start, VFS_SEEK_SET) || ! write_header (0, 0, true, handle)) + return false; + + length = 0; + items = 0; + + if (! write_string_item (tuple, Tuple::Artist, handle, "Artist", & length, & items) || + ! write_string_item (tuple, Tuple::Title, handle, "Title", & length, & items) || + ! write_string_item (tuple, Tuple::Album, handle, "Album", & length, & items) || + ! write_string_item (tuple, Tuple::Comment, handle, "Comment", & length, & items) || + ! write_string_item (tuple, Tuple::Genre, handle, "Genre", & length, & items) || + ! write_integer_item (tuple, Tuple::Track, handle, "Track", & length, & items) || + ! write_integer_item (tuple, Tuple::Year, handle, "Year", & length, & items)) + return false; + + for (const ValuePair & pair : list) + { + if (! strcmp_nocase (pair.key, "Artist") || ! strcmp_nocase (pair.key, "Title") || + ! strcmp_nocase (pair.key, "Album") || ! strcmp_nocase (pair.key, "Comment") || + ! strcmp_nocase (pair.key, "Genre") || ! strcmp_nocase (pair.key, "Track") || + ! strcmp_nocase (pair.key, "Year")) + continue; + + if (! ape_write_item (handle, pair.key, pair.value.begin (), & length)) + return false; + + items ++; + } + + AUDDBG ("Wrote %d items, %d bytes.\n", items, length); + + if (! write_header (length, items, false, handle)) + return false; + + if (handle.fseek (start, VFS_SEEK_SET) < 0) + return false; + + if (! write_header (length, items, true, handle)) + return false; + + return true; +} + +} diff --git a/src/libaudtag/audtag.cc b/src/libaudtag/audtag.cc new file mode 100644 index 0000000..1eef8ca --- /dev/null +++ b/src/libaudtag/audtag.cc @@ -0,0 +1,55 @@ +/* + * audtag.c + * Copyright 2009-2011 Paula Stanciu and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <libaudcore/runtime.h> + +#include "audtag.h" +#include "tag_module.h" + +/* The tuple's file-related attributes are already set */ + +namespace audtag { + +EXPORT bool read_tag (VFSFile & file, Tuple & tuple, Index<char> * image) +{ + TagModule * module = find_tag_module (file, TagType::None); + + if (! module) + { + AUDINFO ("read_tag() not supported for %s\n", file.filename ()); + return false; + } + + return module->read_tag (file, tuple, image); +} + +EXPORT bool write_tuple (VFSFile & file, const Tuple & tuple, TagType new_type) +{ + TagModule * module = find_tag_module (file, new_type); + + if (! module) + { + AUDINFO ("write_tag() not supported for %s\n", file.filename ()); + return false; + } + + return module->write_tag (file, tuple); +} + +} diff --git a/src/libaudtag/audtag.h b/src/libaudtag/audtag.h new file mode 100644 index 0000000..70ec3b7 --- /dev/null +++ b/src/libaudtag/audtag.h @@ -0,0 +1,43 @@ +/* + * audtag.h + * Copyright 2009-2011 Paula Stanciu and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef AUDTAG_H +#define AUDTAG_H + +#include <libaudcore/tuple.h> +#include <libaudcore/vfs.h> + +namespace audtag { + +enum class TagType +{ + None, + APE, + ID3v2 +}; + +bool read_tag (VFSFile & file, Tuple & tuple, Index<char> * image); + +/* new_type specifies the type of tag (see the TagType enum) that should be + * written if the file does not have any existing tag. */ +bool write_tuple (VFSFile & file, const Tuple & tuple, TagType new_type); + +} + +#endif /* AUDTAG_H */ diff --git a/src/libaudtag/builtin.h b/src/libaudtag/builtin.h new file mode 100644 index 0000000..bd5edd9 --- /dev/null +++ b/src/libaudtag/builtin.h @@ -0,0 +1,63 @@ +/* + * builtin.h + * Copyright (c) 2014 Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "tag_module.h" + +#ifndef __LIBAUDTAG_BUILTIN_H__ +#define __LIBAUDTAG_BUILTIN_H__ + +namespace audtag { + +struct ID3v1TagModule : TagModule +{ + constexpr ID3v1TagModule () : TagModule ("ID3v1", TagType::None) {} + + bool can_handle_file (VFSFile & file); + bool read_tag (VFSFile & file, Tuple & tuple, Index<char> * image); +}; + +struct ID3v22TagModule : TagModule +{ + constexpr ID3v22TagModule () : TagModule ("ID3v2.2", TagType::None) {} + + bool can_handle_file (VFSFile & file); + bool read_tag (VFSFile & file, Tuple & tuple, Index<char> * image); +}; + +struct ID3v24TagModule : TagModule +{ + constexpr ID3v24TagModule () : TagModule ("ID3v2.3/v2.4", TagType::ID3v2) {} + + bool can_handle_file (VFSFile & file); + bool read_tag (VFSFile & file, Tuple & tuple, Index<char> * image); + bool write_tag (VFSFile & file, const Tuple & tuple); +}; + +struct APETagModule : TagModule +{ + constexpr APETagModule () : TagModule ("APE", TagType::APE) {} + + bool can_handle_file (VFSFile & file); + bool read_tag (VFSFile & file, Tuple & tuple, Index<char> * image); + bool write_tag (VFSFile & file, const Tuple & tuple); +}; + +} + +#endif diff --git a/src/libaudtag/id3/id3-common.cc b/src/libaudtag/id3/id3-common.cc new file mode 100644 index 0000000..5d6f80a --- /dev/null +++ b/src/libaudtag/id3/id3-common.cc @@ -0,0 +1,334 @@ +/* + * id3-common.c + * Copyright 2010-2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "id3-common.h" + +#include <stdlib.h> +#include <string.h> + +#include <libaudcore/audstrings.h> +#include <libaudcore/runtime.h> + +#include "../util.h" + +#define MAX_STRING 65536 + +#define ID3_ENCODING_LATIN1 0 +#define ID3_ENCODING_UTF16 1 +#define ID3_ENCODING_UTF16_BE 2 +#define ID3_ENCODING_UTF8 3 + +static const void * find_nul_utf16 (const void * mem, int len) +{ + while (len >= 2) + { + if (! ((const char *) mem)[0] && ! ((const char *) mem)[1]) + return mem; + + mem = (char *) mem + 2; + len -= 2; + } + + return nullptr; +} + +static void id3_strnlen (const char * data, int size, int encoding, + int * bytes_without_nul, int * bytes_with_nul) +{ + bool is16 = (encoding == ID3_ENCODING_UTF16 || encoding == ID3_ENCODING_UTF16_BE); + auto nul = (const char *) (is16 ? find_nul_utf16 (data, size) : memchr (data, 0, size)); + + if (nul) + { + if (bytes_without_nul) + * bytes_without_nul = nul - data; + if (bytes_with_nul) + * bytes_with_nul = is16 ? nul + 2 - data : nul + 1 - data; + } + else + { + if (bytes_without_nul) + * bytes_without_nul = size; + if (bytes_with_nul) + * bytes_with_nul = size; + } +} + +static StringBuf id3_convert (const char * data, int size, int encoding) +{ + if (encoding == ID3_ENCODING_UTF16) + return str_convert (data, aud::min (size, 2 * MAX_STRING), "UTF-16", "UTF-8"); + else if (encoding == ID3_ENCODING_UTF16_BE) + return str_convert (data, aud::min (size, 2 * MAX_STRING), "UTF-16BE", "UTF-8"); + else + return str_to_utf8 (data, aud::min (size, MAX_STRING)); +} + +static StringBuf id3_decode_text (const char * data, int size) +{ + if (size < 1) + return StringBuf (); + + int real_size; + id3_strnlen (data + 1, size - 1, data[0], & real_size, nullptr); + return id3_convert (data + 1, real_size, data[0]); +} + +void id3_associate_string (Tuple & tuple, Tuple::Field field, const char * data, int size) +{ + StringBuf text = id3_decode_text (data, size); + + if (text && text[0]) + { + AUDDBG ("Field %i = %s.\n", field, (const char *) text); + tuple.set_str (field, text); + } +} + +void id3_associate_int (Tuple & tuple, Tuple::Field field, const char * data, int size) +{ + StringBuf text = id3_decode_text (data, size); + + /* Ignore zeros here. In particular, there are many ID3 tags with invalid + * TLEN fields floating around, and we want to let mpg123 recalculate the + * length in such cases. */ + if (text && atoi (text) > 0) + { + AUDDBG ("Field %i = %s.\n", field, (const char *) text); + tuple.set_int (field, atoi (text)); + } +} + +void id3_associate_length (Tuple & tuple, const char * data, int size) +{ + StringBuf text = id3_decode_text (data, size); + int decoder_length = tuple.get_int (Tuple::Length); + int tlen_length; + + AUDDBG ("Length, decoder length: %i, tag length: %s.\n", decoder_length, (const char *) text); + + if (text && (tlen_length = atoi (text))) + { + if (decoder_length <= 0 || + (tlen_length > (decoder_length / 2) && tlen_length < (decoder_length * 2))) + tuple.set_int (Tuple::Length, tlen_length); + } +} + +void id3_decode_genre (Tuple & tuple, const char * data, int size) +{ + StringBuf text = id3_decode_text (data, size); + int numericgenre; + + if (! text) + return; + + if (text[0] == '(') + numericgenre = atoi (text + 1); + else + numericgenre = atoi (text); + + if (numericgenre > 0) + tuple.set_str (Tuple::Genre, convert_numericgenre_to_text (numericgenre)); + else + tuple.set_str (Tuple::Genre, text); +} + +void id3_decode_comment (Tuple & tuple, const char * data, int size) +{ + if (size < 4) + return; + + int before_nul, after_nul; + id3_strnlen (data + 4, size - 4, data[0], & before_nul, & after_nul); + + const char * lang = data + 1; + StringBuf type = id3_convert (data + 4, before_nul, data[0]); + StringBuf value = id3_convert (data + 4 + after_nul, size - 4 - after_nul, data[0]); + + AUDDBG ("Comment: lang = %.3s, type = %s, value = %s.\n", lang, + (const char *) type, (const char *) value); + + if (type && ! type[0] && value) /* blank type = actual comment */ + tuple.set_str (Tuple::Comment, value); +} + +static bool decode_rva_block (const char * * _data, int * _size, + int * channel, int * adjustment, int * adjustment_unit, int * peak, + int * peak_unit) +{ + const char * data = * _data; + int size = * _size; + int peak_bits; + + if (size < 4) + return false; + + * channel = (unsigned char) data[0]; + /* first byte is signed, but C/C++ allows shifting only unsigned values */ + * adjustment = (int16_t) ((unsigned char) data[1] << 8) | (unsigned char) data[2]; + * adjustment_unit = 512; + peak_bits = (unsigned char) data[3]; + + data += 4; + size -= 4; + + AUDDBG ("RVA block: channel = %d, adjustment = %d/%d, peak bits = %d\n", + * channel, * adjustment, * adjustment_unit, peak_bits); + + if (peak_bits > 0 && peak_bits < (int) sizeof (int) * 8) + { + int bytes = (peak_bits + 7) / 8; + int count; + + if (bytes > size) + return false; + + * peak = 0; + * peak_unit = 1 << peak_bits; + + for (count = 0; count < bytes; count ++) + * peak = (* peak << 8) | (unsigned char) data[count]; + + data += bytes; + size -= count; + + AUDDBG ("RVA block: peak = %d/%d\n", * peak, * peak_unit); + } + else + { + * peak = 0; + * peak_unit = 0; + } + + * _data = data; + * _size = size; + return true; +} + +void id3_decode_rva (Tuple & tuple, const char * data, int size) +{ + const char * domain; + int channel, adjustment, adjustment_unit, peak, peak_unit; + + if (memchr (data, 0, size) == nullptr) + return; + + domain = data; + + AUDDBG ("RVA domain: %s\n", domain); + + size -= strlen (domain) + 1; + data += strlen (domain) + 1; + + while (size > 0) + { + if (! decode_rva_block (& data, & size, & channel, & adjustment, + & adjustment_unit, & peak, & peak_unit)) + break; + + if (channel != 1) /* specific channel? */ + continue; + + if (tuple.get_value_type (Tuple::GainDivisor) == Tuple::Int) + adjustment = adjustment * (int64_t) tuple.get_int + (Tuple::GainDivisor) / adjustment_unit; + else + tuple.set_int (Tuple::GainDivisor, adjustment_unit); + + if (peak_unit) + { + if (tuple.get_value_type (Tuple::PeakDivisor) == Tuple::Int) + peak = peak * (int64_t) tuple.get_int (Tuple::PeakDivisor) / peak_unit; + else + tuple.set_int (Tuple::PeakDivisor, peak_unit); + } + + if (! strcmp_nocase (domain, "album")) + { + tuple.set_int (Tuple::AlbumGain, adjustment); + + if (peak_unit) + tuple.set_int (Tuple::AlbumPeak, peak); + } + else if (! strcmp_nocase (domain, "track")) + { + tuple.set_int (Tuple::TrackGain, adjustment); + + if (peak_unit) + tuple.set_int (Tuple::TrackPeak, peak); + } + } +} + +void id3_decode_txxx (Tuple & tuple, const char * data, int size) +{ + if (size < 1) + return; + + int before_nul, after_nul; + id3_strnlen (data + 1, size - 1, data[0], & before_nul, & after_nul); + + StringBuf key = id3_convert (data + 1, before_nul, data[0]); + StringBuf value = id3_convert (data + 1 + after_nul, size - 1 - after_nul, data[0]); + + AUDDBG ("Key-value: %s = %s.\n", (const char *) key, (const char *) value); + + if (key && value) + { + if (! strcmp_nocase (key, "REPLAYGAIN_TRACK_GAIN")) + tuple.set_gain (Tuple::TrackGain, Tuple::GainDivisor, value); + else if (! strcmp_nocase (key, "REPLAYGAIN_TRACK_PEAK")) + tuple.set_gain (Tuple::TrackPeak, Tuple::PeakDivisor, value); + else if (! strcmp_nocase (key, "REPLAYGAIN_ALBUM_GAIN")) + tuple.set_gain (Tuple::AlbumGain, Tuple::GainDivisor, value); + else if (! strcmp_nocase (key, "REPLAYGAIN_ALBUM_PEAK")) + tuple.set_gain (Tuple::AlbumPeak, Tuple::PeakDivisor, value); + } +} + +Index<char> id3_decode_picture (const char * data, int size) +{ + Index<char> buf; + + const char * nul; + if (size < 2 || ! (nul = (char *) memchr (data + 1, 0, size - 2))) + return buf; + + int type = (unsigned char) nul[1]; + + const char * body = nul + 2; + int body_size = data + size - body; + + int before_nul2, after_nul2; + id3_strnlen (body, body_size, data[0], & before_nul2, & after_nul2); + + const char * mime = data + 1; + StringBuf desc = id3_convert (body, before_nul2, data[0]); + + int image_size = body_size - after_nul2; + + AUDDBG ("Picture: mime = %s, type = %d, desc = %s, size = %d.\n", mime, + type, (const char *) desc, image_size); + + if (type == 3 || type == 0) /* album cover or iTunes */ + buf.insert (body + after_nul2, 0, image_size); + + return buf; +} diff --git a/src/libaudtag/id3/id3-common.h b/src/libaudtag/id3/id3-common.h new file mode 100644 index 0000000..eab5616 --- /dev/null +++ b/src/libaudtag/id3/id3-common.h @@ -0,0 +1,36 @@ +/* + * id3-common.h + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef AUDTAG_ID3_COMMON_H +#define AUDTAG_ID3_COMMON_H + +#include <libaudcore/index.h> +#include <libaudcore/tuple.h> + +void id3_associate_string (Tuple & tuple, Tuple::Field field, const char * data, int size); +void id3_associate_int (Tuple & tuple, Tuple::Field field, const char * data, int size); +void id3_associate_length (Tuple & tuple, const char * data, int size); +void id3_decode_genre (Tuple & tuple, const char * data, int size); +void id3_decode_comment (Tuple & tuple, const char * data, int size); +void id3_decode_rva (Tuple & tuple, const char * data, int size); +void id3_decode_txxx (Tuple & tuple, const char * data, int size); + +Index<char> id3_decode_picture (const char * data, int size); + +#endif diff --git a/src/libaudtag/id3/id3v1.cc b/src/libaudtag/id3/id3v1.cc new file mode 100644 index 0000000..65ec9e5 --- /dev/null +++ b/src/libaudtag/id3/id3v1.cc @@ -0,0 +1,132 @@ +/* + * id3v1.c + * Copyright 2013 John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stdlib.h> +#include <string.h> + +#include <glib.h> /* for g_strchomp */ + +#include <libaudcore/audstrings.h> +#include <libaudtag/builtin.h> +#include <libaudtag/util.h> + +#pragma pack(push) +#pragma pack(1) + +struct ID3v1Tag { + char header[3]; + char title[30]; + char artist[30]; + char album[30]; + char year[4]; + char comment[30]; + unsigned char genre; +}; + +struct ID3v1Ext { + char header[4]; + char title[60]; + char artist[60]; + char album[60]; + unsigned char speed; + char genre[30]; + char start[6]; + char end[6]; +}; + +#pragma pack(pop) + +namespace audtag { + +static bool read_id3v1_tag (VFSFile & file, ID3v1Tag * tag) +{ + if (file.fseek (-sizeof (ID3v1Tag), VFS_SEEK_END) < 0) + return false; + if (file.fread (tag, 1, sizeof (ID3v1Tag)) != sizeof (ID3v1Tag)) + return false; + + return ! strncmp (tag->header, "TAG", 3); +} + +static bool read_id3v1_ext (VFSFile & file, ID3v1Ext * ext) +{ + if (file.fseek (-(sizeof (ID3v1Ext) + sizeof (ID3v1Tag)), VFS_SEEK_END) < 0) + return false; + if (file.fread (ext, 1, sizeof (ID3v1Ext)) != sizeof (ID3v1Ext)) + return false; + + return ! strncmp (ext->header, "TAG+", 4); +} + +bool ID3v1TagModule::can_handle_file (VFSFile & file) +{ + ID3v1Tag tag; + return read_id3v1_tag (file, & tag); +} + +static bool combine_string (Tuple & tuple, Tuple::Field field, + const char * str1, int size1, const char * str2, int size2) +{ + StringBuf str = str_copy (str1, strlen_bounded (str1, size1)); + str.insert (-1, str2, strlen_bounded (str2, size2)); + + g_strchomp (str); + str.resize (strlen (str)); + + if (! str.len ()) + return false; + + tuple.set_str (field, str); + return true; +} + +bool ID3v1TagModule::read_tag (VFSFile & file, Tuple & tuple, Index<char> * image) +{ + ID3v1Tag tag; + ID3v1Ext ext; + + if (! read_id3v1_tag (file, & tag)) + return false; + + if (! read_id3v1_ext (file, & ext)) + memset (& ext, 0, sizeof (ID3v1Ext)); + + combine_string (tuple, Tuple::Title, tag.title, sizeof tag.title, ext.title, sizeof ext.title); + combine_string (tuple, Tuple::Artist, tag.artist, sizeof tag.artist, ext.artist, sizeof ext.artist); + combine_string (tuple, Tuple::Album, tag.album, sizeof tag.album, ext.album, sizeof ext.album); + combine_string (tuple, Tuple::Comment, tag.comment, sizeof tag.comment, nullptr, 0); + + StringBuf year = str_copy (tag.year, strlen_bounded (tag.year, 4)); + if (atoi (year)) + tuple.set_int (Tuple::Year, atoi (year)); + + if (! tag.comment[28] && tag.comment[29]) + tuple.set_int (Tuple::Track, (unsigned char) tag.comment[29]); + + if (! combine_string (tuple, Tuple::Genre, ext.genre, sizeof ext.genre, nullptr, 0)) + { + const char * genre = convert_numericgenre_to_text (tag.genre); + if (genre) + tuple.set_str (Tuple::Genre, genre); + } + + return true; +} + +} diff --git a/src/libaudtag/id3/id3v22.cc b/src/libaudtag/id3/id3v22.cc new file mode 100644 index 0000000..f5e950c --- /dev/null +++ b/src/libaudtag/id3/id3v22.cc @@ -0,0 +1,294 @@ +/* + * id3v22.c + * Copyright 2009-2014 Paula Stanciu, Tony Vroon, John Lindgren, + * and Ariadne Conill + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stdlib.h> +#include <string.h> + +#define WANT_AUD_BSWAP +#include <libaudcore/audio.h> +#include <libaudcore/audstrings.h> +#include <libaudcore/runtime.h> +#include <libaudtag/builtin.h> +#include <libaudtag/util.h> + +#include "id3-common.h" + +enum +{ + ID3_ALBUM = 0, + ID3_TITLE, + ID3_COMPOSER, + ID3_COPYRIGHT, + ID3_DATE, + ID3_LENGTH, + ID3_ARTIST, + ID3_ALBUM_ARTIST, + ID3_TRACKNR, + ID3_YEAR, + ID3_GENRE, + ID3_COMMENT, + ID3_ENCODER, + ID3_TXX, + ID3_RVA, + ID3_PIC, + ID3_TAGS_NO +}; + +static const char * id3_frames[ID3_TAGS_NO] = { + "TAL", + "TT2", + "TCM", + "TCR", + "TDA", + "TLE", + "TP1", + "TP2", + "TRK", + "TYE", + "TCO", + "COM", + "TSS", + "TXX", + "RVA", + "PIC" +}; + +#pragma pack(push) /* must be byte-aligned */ +#pragma pack(1) +struct ID3v22Header { + char magic[3]; + unsigned char version; + unsigned char revision; + unsigned char flags; + uint32_t size; +}; + +struct ID3v22FrameHeader { + char key[3]; + unsigned char size[3]; +}; +#pragma pack(pop) + +struct GenericFrame : public Index<char> { + String key; +}; + +#define ID3_HEADER_SYNCSAFE 0x40 +#define ID3_HEADER_COMPRESSED 0x20 + +namespace audtag { + +static bool validate_header (ID3v22Header * header) +{ + if (memcmp (header->magic, "ID3", 3)) + return false; + + if ((header->version != 2)) + return false; + + header->size = unsyncsafe32 (FROM_BE32 (header->size)); + + AUDDBG ("Found ID3v2 header:\n"); + AUDDBG (" magic = %.3s\n", header->magic); + AUDDBG (" version = %d\n", (int) header->version); + AUDDBG (" revision = %d\n", (int) header->revision); + AUDDBG (" flags = %x\n", (int) header->flags); + AUDDBG (" size = %d\n", (int) header->size); + return true; +} + +static bool read_header (VFSFile & handle, int * version, bool * + syncsafe, int64_t * offset, int * header_size, int * data_size) +{ + ID3v22Header header; + + if (handle.fseek (0, VFS_SEEK_SET)) + return false; + + if (handle.fread (& header, 1, sizeof (ID3v22Header)) != sizeof + (ID3v22Header)) + return false; + + if (validate_header (& header)) + { + * offset = 0; + * version = header.version; + * header_size = sizeof (ID3v22Header); + * data_size = header.size; + } + else + return false; + + * syncsafe = (header.flags & ID3_HEADER_SYNCSAFE) ? true : false; + + AUDDBG ("Offset = %d, header size = %d, data size = %d\n", + (int) * offset, * header_size, * data_size); + + return true; +} + +static bool read_frame (VFSFile & handle, int max_size, int version, + bool syncsafe, int * frame_size, GenericFrame & frame) +{ + ID3v22FrameHeader header; + uint32_t hdrsz = 0; + + if ((max_size -= sizeof (ID3v22FrameHeader)) < 0) + return false; + + if (handle.fread (& header, 1, sizeof (ID3v22FrameHeader)) != sizeof + (ID3v22FrameHeader)) + return false; + + if (! header.key[0]) /* padding */ + return false; + + for (int i = 0; i < 3; i++) + { + hdrsz |= (uint32_t) header.size[i] << ((2 - i) * 8); + AUDDBG ("header.size[%d] = %d hdrsz %d slot %d\n", i, header.size[i], hdrsz, 2 - i); + } + + if (hdrsz > (unsigned) max_size || hdrsz == 0) + return false; + + AUDDBG ("Found frame:\n"); + AUDDBG (" key = %.3s\n", header.key); + AUDDBG (" size = %d\n", (int) hdrsz); + + * frame_size = sizeof (ID3v22FrameHeader) + hdrsz; + + frame.key = String (str_copy (header.key, 3)); + frame.clear (); + frame.insert (0, hdrsz); + + if (handle.fread (& frame[0], 1, frame.len ()) != frame.len ()) + return false; + + AUDDBG ("Data size = %d.\n", frame.len ()); + return true; +} + + +static int get_frame_id (const char * key) +{ + int id; + + for (id = 0; id < ID3_TAGS_NO; id ++) + { + if (! strcmp (key, id3_frames[id])) + return id; + } + + return -1; +} + +bool ID3v22TagModule::can_handle_file (VFSFile & handle) +{ + int version, header_size, data_size; + bool syncsafe; + int64_t offset; + + return read_header (handle, & version, & syncsafe, & offset, & header_size, + & data_size); +} + +bool ID3v22TagModule::read_tag (VFSFile & handle, Tuple & tuple, Index<char> * image) +{ + int version, header_size, data_size; + bool syncsafe; + int64_t offset; + int pos; + + if (! read_header (handle, & version, & syncsafe, & offset, & header_size, + & data_size)) + return false; + + AUDDBG ("Reading tags from %i bytes of ID3 data in %s\n", data_size, + handle.filename ()); + + for (pos = 0; pos < data_size; ) + { + int frame_size; + GenericFrame frame; + + if (! read_frame (handle, data_size - pos, version, syncsafe, & frame_size, frame)) + { + AUDDBG("read_frame failed at pos %i\n", pos); + break; + } + + switch (get_frame_id (frame.key)) + { + case ID3_ALBUM: + id3_associate_string (tuple, Tuple::Album, & frame[0], frame.len ()); + break; + case ID3_TITLE: + id3_associate_string (tuple, Tuple::Title, & frame[0], frame.len ()); + break; + case ID3_COMPOSER: + id3_associate_string (tuple, Tuple::Composer, & frame[0], frame.len ()); + break; + case ID3_COPYRIGHT: + id3_associate_string (tuple, Tuple::Copyright, & frame[0], frame.len ()); + break; + case ID3_DATE: + id3_associate_string (tuple, Tuple::Date, & frame[0], frame.len ()); + break; + case ID3_LENGTH: + id3_associate_length (tuple, & frame[0], frame.len ()); + break; + case ID3_ARTIST: + id3_associate_string (tuple, Tuple::Artist, & frame[0], frame.len ()); + break; + case ID3_ALBUM_ARTIST: + id3_associate_string (tuple, Tuple::AlbumArtist, & frame[0], frame.len ()); + break; + case ID3_TRACKNR: + id3_associate_int (tuple, Tuple::Track, & frame[0], frame.len ()); + break; + case ID3_YEAR: + id3_associate_int (tuple, Tuple::Year, & frame[0], frame.len ()); + break; + case ID3_GENRE: + id3_decode_genre (tuple, & frame[0], frame.len ()); + break; + case ID3_COMMENT: + id3_decode_comment (tuple, & frame[0], frame.len ()); + break; + case ID3_RVA: + id3_decode_rva (tuple, & frame[0], frame.len ()); + break; + case ID3_PIC: + if (image) + * image = id3_decode_picture (& frame[0], frame.len ()); + break; + default: + AUDDBG ("Ignoring unsupported ID3 frame %s.\n", (const char *) frame.key); + break; + } + + pos += frame_size; + } + + return true; +} + +} diff --git a/src/libaudtag/id3/id3v24.cc b/src/libaudtag/id3/id3v24.cc new file mode 100644 index 0000000..b27163f --- /dev/null +++ b/src/libaudtag/id3/id3v24.cc @@ -0,0 +1,691 @@ +/* + * id3v24.c + * Copyright 2009-2014 Paula Stanciu, Tony Vroon, John Lindgren, + * Mikael Magnusson, and Michał Lipski + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <glib.h> /* for g_utf8_to_utf16 */ + +#define WANT_AUD_BSWAP +#include <libaudcore/audio.h> +#include <libaudcore/audstrings.h> +#include <libaudcore/multihash.h> +#include <libaudcore/runtime.h> +#include <libaudtag/builtin.h> +#include <libaudtag/util.h> + +#include "id3-common.h" + +#define MAX_TAG_SIZE 16777216 /* reject tags over 16 MB */ + +enum +{ + ID3_ALBUM = 0, + ID3_TITLE, + ID3_COMPOSER, + ID3_COPYRIGHT, + ID3_DATE, + ID3_LENGTH, + ID3_ARTIST, + ID3_ALBUM_ARTIST, + ID3_TRACKNR, + ID3_YEAR, + ID3_GENRE, + ID3_COMMENT, + ID3_ENCODER, + ID3_RECORDING_TIME, + ID3_TXXX, + ID3_RVA2, + ID3_APIC, + ID3_TAGS_NO +}; + +static const char * id3_frames[ID3_TAGS_NO] = { + "TALB", + "TIT2", + "TCOM", + "TCOP", + "TDAT", + "TLEN", + "TPE1", + "TPE2", + "TRCK", + "TYER", + "TCON", + "COMM", + "TSSE", + "TDRC", + "TXXX", + "RVA2", + "APIC" +}; + +#pragma pack(push) /* must be byte-aligned */ +#pragma pack(1) +struct ID3v24Header { + char magic[3]; + unsigned char version; + unsigned char revision; + unsigned char flags; + uint32_t size; +}; + +struct ID3v24FrameHeader { + char key[4]; + uint32_t size; + uint16_t flags; +}; +#pragma pack(pop) + +struct GenericFrame : public Index<char> { + String key; +}; + +typedef Index<GenericFrame> FrameList; +typedef SimpleHash<String, FrameList> FrameDict; + +#define ID3_HEADER_SYNCSAFE 0x80 +#define ID3_HEADER_HAS_EXTENDED_HEADER 0x40 +#define ID3_HEADER_HAS_FOOTER 0x10 + +#define ID3_FRAME_HAS_GROUP 0x0040 +#define ID3_FRAME_COMPRESSED 0x0008 +#define ID3_FRAME_ENCRYPTED 0x0004 +#define ID3_FRAME_SYNCSAFE 0x0002 +#define ID3_FRAME_HAS_LENGTH 0x0001 + +namespace audtag { + +static bool skip_extended_header_3 (VFSFile & handle, int * _size) +{ + uint32_t size; + + if (handle.fread (& size, 1, 4) != 4) + return false; + + size = FROM_BE32 (size); + + AUDDBG ("Found v2.3 extended header, size = %d.\n", (int) size); + + if (handle.fseek (size, VFS_SEEK_CUR)) + return false; + + * _size = 4 + size; + return true; +} + +static bool skip_extended_header_4 (VFSFile & handle, int * _size) +{ + uint32_t size; + + if (handle.fread (& size, 1, 4) != 4) + return false; + + size = unsyncsafe32 (FROM_BE32 (size)); + + AUDDBG ("Found v2.4 extended header, size = %d.\n", (int) size); + + if (handle.fseek (size - 4, VFS_SEEK_CUR)) + return false; + + * _size = size; + return true; +} + +static bool validate_header (ID3v24Header * header, bool is_footer) +{ + if (memcmp (header->magic, is_footer ? "3DI" : "ID3", 3)) + return false; + + if ((header->version != 3 && header->version != 4) || header->revision != 0) + return false; + + header->size = unsyncsafe32 (FROM_BE32 (header->size)); + if (header->size > MAX_TAG_SIZE) + return false; + + AUDDBG ("Found ID3v2 %s:\n", is_footer ? "footer" : "header"); + AUDDBG (" magic = %.3s\n", header->magic); + AUDDBG (" version = %d\n", (int) header->version); + AUDDBG (" revision = %d\n", (int) header->revision); + AUDDBG (" flags = %x\n", (int) header->flags); + AUDDBG (" size = %d\n", (int) header->size); + return true; +} + +static bool read_header (VFSFile & handle, int * version, bool * + syncsafe, int64_t * offset, int * header_size, int * data_size, int * + footer_size) +{ + ID3v24Header header, footer; + + if (handle.fseek (0, VFS_SEEK_SET)) + return false; + + if (handle.fread (& header, 1, sizeof (ID3v24Header)) != sizeof (ID3v24Header)) + return false; + + if (validate_header (& header, false)) + { + * offset = 0; + * version = header.version; + * header_size = sizeof (ID3v24Header); + * data_size = header.size; + + if (header.flags & ID3_HEADER_HAS_FOOTER) + { + if (handle.fseek (header.size, VFS_SEEK_CUR)) + return false; + + if (handle.fread (& footer, 1, sizeof (ID3v24Header)) != sizeof (ID3v24Header)) + return false; + + if (! validate_header (& footer, true)) + return false; + + if (handle.fseek (sizeof (ID3v24Header), VFS_SEEK_SET)) + return false; + + * footer_size = sizeof (ID3v24Header); + } + else + * footer_size = 0; + } + else + { + int64_t end = handle.fsize (); + + if (end < 0) + return false; + + if (handle.fseek (end - sizeof (ID3v24Header), VFS_SEEK_SET)) + return false; + + if (handle.fread (& footer, 1, sizeof (ID3v24Header)) != sizeof (ID3v24Header)) + return false; + + if (! validate_header (& footer, true)) + return false; + + * offset = end - 2 * sizeof (ID3v24Header) - footer.size; + * version = footer.version; + * header_size = sizeof (ID3v24Header); + * data_size = footer.size; + * footer_size = sizeof (ID3v24Header); + + if (handle.fseek (* offset, VFS_SEEK_SET)) + return false; + + if (handle.fread (& header, 1, sizeof (ID3v24Header)) != sizeof + (ID3v24Header)) + return false; + + if (! validate_header (& header, false)) + return false; + } + + // this flag indicates tag-level unsynchronisation in ID3v2.3 + // ID3v2.4 uses frame-level unsynchronisation, rendering this flag meaningless + * syncsafe = (* version == 3) && (header.flags & ID3_HEADER_SYNCSAFE); + + if (header.flags & ID3_HEADER_HAS_EXTENDED_HEADER) + { + int extended_size = 0; + + if (header.version == 3) + { + if (! skip_extended_header_3 (handle, & extended_size)) + return false; + } + else if (header.version == 4) + { + if (! skip_extended_header_4 (handle, & extended_size)) + return false; + } + + if (extended_size > * data_size) + return false; + + * header_size += extended_size; + * data_size -= extended_size; + } + + AUDDBG ("Offset = %d, header size = %d, data size = %d, footer size = " + "%d.\n", (int) * offset, * header_size, * data_size, * footer_size); + + return true; +} + +static void unsyncsafe (Index<char> & data) +{ + const char * get = data.begin (), * end = data.end (); + char * set = data.begin (); + const char * c; + + while ((c = (const char *) memchr (get, 0xff, end - get))) + { + c ++; + memmove (set, get, c - get); + set += c - get; + get = c; + + if (get < end && ! get[0]) + get ++; + } + + memmove (set, get, end - get); + set += end - get; + + data.remove (set - data.begin (), -1); +} + +static Index<char> read_tag_data (VFSFile & handle, int size, bool syncsafe) +{ + Index<char> data; + data.resize (size); + data.resize (handle.fread (data.begin (), 1, size)); + + if (syncsafe) + unsyncsafe (data); + + return data; +} + +static bool read_frame (const char * data, int max_size, int version, + int * frame_size, GenericFrame & frame) +{ + ID3v24FrameHeader header; + unsigned skip = 0; + + if ((max_size -= sizeof (ID3v24FrameHeader)) < 0) + return false; + + memcpy (& header, data, sizeof (ID3v24FrameHeader)); + data += sizeof (ID3v24FrameHeader); + + if (! header.key[0]) /* padding */ + return false; + + header.size = (version == 3) ? FROM_BE32 (header.size) : unsyncsafe32 (FROM_BE32 (header.size)); + header.flags = FROM_BE16 (header.flags); + + if (header.size > (unsigned) max_size || header.size == 0) + return false; + + AUDDBG ("Found frame:\n"); + AUDDBG (" key = %.4s\n", header.key); + AUDDBG (" size = %d\n", (int) header.size); + AUDDBG (" flags = %x\n", (int) header.flags); + + if (header.flags & (ID3_FRAME_COMPRESSED | ID3_FRAME_ENCRYPTED)) + { + AUDDBG ("Hit compressed/encrypted frame %.4s.\n", header.key); + return false; + } + + if (header.flags & ID3_FRAME_HAS_GROUP) + skip ++; + if (header.flags & ID3_FRAME_HAS_LENGTH) + skip += 4; + + if (skip >= header.size) + return false; + + * frame_size = sizeof (ID3v24FrameHeader) + header.size; + + frame.key = String (str_copy (header.key, 4)); + frame.clear (); + frame.insert (data + skip, 0, header.size - skip); + + if (header.flags & ID3_FRAME_SYNCSAFE) + unsyncsafe (frame); + + AUDDBG ("Data size = %d.\n", frame.len ()); + return true; +} + +static void read_all_frames (const Index<char> & data, int version, FrameDict & dict) +{ + for (const char * pos = data.begin (); pos < data.end (); ) + { + int frame_size; + GenericFrame frame; + + if (! read_frame (pos, data.end () - pos, version, & frame_size, frame)) + break; + + pos += frame_size; + + FrameList * list = dict.lookup (frame.key); + if (! list) + list = dict.add (frame.key, FrameList ()); + + list->append (std::move (frame)); + } +} + +static bool write_frame (VFSFile & file, const GenericFrame & frame, int version, int * frame_size) +{ + AUDDBG ("Writing frame %s, size %d\n", (const char *) frame.key, frame.len ()); + + ID3v24FrameHeader header; + + strncpy (header.key, frame.key, 4); + + uint32_t size = frame.len (); + if (version > 3) + size = syncsafe32 (size); + + header.size = TO_BE32 (size); + header.flags = 0; + + if (file.fwrite (& header, 1, sizeof (ID3v24FrameHeader)) != sizeof (ID3v24FrameHeader)) + return false; + + if (file.fwrite (& frame[0], 1, frame.len ()) != frame.len ()) + return false; + + * frame_size = sizeof (ID3v24FrameHeader) + frame.len (); + return true; +} + +static int write_all_frames (VFSFile & file, FrameDict & dict, int version) +{ + int written_size = 0; + + dict.iterate ([&] (const String & key, FrameList & list) + { + for (const GenericFrame & frame : list) + { + int size; + if (write_frame (file, frame, version, & size)) + written_size += size; + } + }); + + AUDDBG ("Total frame bytes written = %d.\n", written_size); + return written_size; +} + +static bool write_header (VFSFile & file, int version, int size) +{ + ID3v24Header header; + + memcpy (header.magic, "ID3", 3); + header.version = version; + header.revision = 0; + header.flags = 0; + header.size = TO_BE32 (syncsafe32 (size)); + + return file.fwrite (& header, 1, sizeof (ID3v24Header)) == sizeof (ID3v24Header); +} + +static int get_frame_id (const char * key) +{ + for (int id = 0; id < ID3_TAGS_NO; id ++) + { + if (! strcmp (key, id3_frames[id])) + return id; + } + + return -1; +} + +static GenericFrame & add_generic_frame (int id, int size, FrameDict & dict) +{ + String key (id3_frames[id]); + FrameList * list = dict.add (key, FrameList ()); + + GenericFrame & frame = list->append (); + + frame.key = key; + frame.insert (0, size); + + return frame; +} + +static void remove_frame (int id, FrameDict & dict) +{ + AUDDBG ("Deleting frame %s.\n", id3_frames[id]); + dict.remove (String (id3_frames[id])); +} + +static void add_text_frame (int id, const char * text, FrameDict & dict) +{ + if (! text) + { + remove_frame (id, dict); + return; + } + + AUDDBG ("Adding text frame %s = %s.\n", id3_frames[id], text); + + long words; + uint16_t * utf16 = g_utf8_to_utf16 (text, -1, nullptr, & words, nullptr); + g_return_if_fail (utf16); + + GenericFrame & frame = add_generic_frame (id, 3 + 2 * words, dict); + + frame[0] = 1; /* UTF-16 encoding */ + * (uint16_t *) (& frame[1]) = 0xfeff; /* byte order mark */ + memcpy (& frame[3], utf16, 2 * words); + + g_free (utf16); +} + +static void add_comment_frame (const char * text, FrameDict & dict) +{ + if (! text) + { + remove_frame (ID3_COMMENT, dict); + return; + } + + AUDDBG ("Adding comment frame = %s.\n", text); + + long words; + uint16_t * utf16 = g_utf8_to_utf16 (text, -1, nullptr, & words, nullptr); + g_return_if_fail (utf16); + + GenericFrame & frame = add_generic_frame (ID3_COMMENT, 10 + 2 * words, dict); + + frame[0] = 1; /* UTF-16 encoding */ + memcpy (& frame[1], "eng", 3); /* language */ + * (uint16_t *) (& frame[4]) = 0xfeff; /* byte order mark */ + * (uint16_t *) (& frame[6]) = 0; /* end of content description */ + * (uint16_t *) (& frame[8]) = 0xfeff; /* byte order mark */ + memcpy (& frame[10], utf16, 2 * words); + + g_free (utf16); +} + +static void add_frameFromTupleStr (const Tuple & tuple, Tuple::Field field, + int id3_field, FrameDict & dict) +{ + add_text_frame (id3_field, tuple.get_str (field), dict); +} + +static void add_frameFromTupleInt (const Tuple & tuple, Tuple::Field field, + int id3_field, FrameDict & dict) +{ + if (tuple.get_value_type (field) == Tuple::Int) + add_text_frame (id3_field, int_to_str (tuple.get_int (field)), dict); + else + remove_frame (id3_field, dict); +} + +bool ID3v24TagModule::can_handle_file (VFSFile & handle) +{ + int version, header_size, data_size, footer_size; + bool syncsafe; + int64_t offset; + + return read_header (handle, & version, & syncsafe, & offset, & header_size, + & data_size, & footer_size); +} + +bool ID3v24TagModule::read_tag (VFSFile & handle, Tuple & tuple, Index<char> * image) +{ + int version, header_size, data_size, footer_size; + bool syncsafe; + int64_t offset; + + if (! read_header (handle, & version, & syncsafe, & offset, & header_size, + & data_size, & footer_size)) + return false; + + Index<char> data = read_tag_data (handle, data_size, syncsafe); + FrameList rva_frames; + + for (const char * pos = data.begin (); pos < data.end (); ) + { + int frame_size; + GenericFrame frame; + + if (! read_frame (pos, data.end () - pos, version, & frame_size, frame)) + break; + + switch (get_frame_id (frame.key)) + { + case ID3_ALBUM: + id3_associate_string (tuple, Tuple::Album, & frame[0], frame.len ()); + break; + case ID3_TITLE: + id3_associate_string (tuple, Tuple::Title, & frame[0], frame.len ()); + break; + case ID3_COMPOSER: + id3_associate_string (tuple, Tuple::Composer, & frame[0], frame.len ()); + break; + case ID3_COPYRIGHT: + id3_associate_string (tuple, Tuple::Copyright, & frame[0], frame.len ()); + break; + case ID3_DATE: + id3_associate_string (tuple, Tuple::Date, & frame[0], frame.len ()); + break; + case ID3_LENGTH: + id3_associate_length (tuple, & frame[0], frame.len ()); + break; + case ID3_ARTIST: + id3_associate_string (tuple, Tuple::Artist, & frame[0], frame.len ()); + break; + case ID3_ALBUM_ARTIST: + id3_associate_string (tuple, Tuple::AlbumArtist, & frame[0], frame.len ()); + break; + case ID3_TRACKNR: + id3_associate_int (tuple, Tuple::Track, & frame[0], frame.len ()); + break; + case ID3_YEAR: + case ID3_RECORDING_TIME: + id3_associate_int (tuple, Tuple::Year, & frame[0], frame.len ()); + break; + case ID3_GENRE: + id3_decode_genre (tuple, & frame[0], frame.len ()); + break; + case ID3_COMMENT: + id3_decode_comment (tuple, & frame[0], frame.len ()); + break; + case ID3_TXXX: + id3_decode_txxx (tuple, & frame[0], frame.len ()); + break; + case ID3_RVA2: + rva_frames.append (std::move (frame)); + break; + case ID3_APIC: + if (image) + * image = id3_decode_picture (& frame[0], frame.len ()); + break; + default: + AUDDBG ("Ignoring unsupported ID3 frame %s.\n", (const char *) frame.key); + break; + } + + pos += frame_size; + } + + /* only decode RVA2 frames if Replay Gain was not found in TXXX frames */ + if (! tuple.is_set (Tuple::GainDivisor) && ! tuple.is_set (Tuple::PeakDivisor)) + { + for (auto & rva : rva_frames) + id3_decode_rva (tuple, & rva[0], rva.len ()); + } + + return true; +} + +bool ID3v24TagModule::write_tag (VFSFile & f, const Tuple & tuple) +{ + int version = 3; + int header_size, data_size, footer_size; + bool syncsafe; + int64_t offset; + + //read all frames into generic frames; + FrameDict dict; + + if (read_header (f, & version, & syncsafe, & offset, & header_size, & data_size, & footer_size)) + read_all_frames (read_tag_data (f, data_size, syncsafe), version, dict); + else + offset = header_size = data_size = footer_size = 0; + + //make the new frames from tuple and replace in the dictionary the old frames with the new ones + add_frameFromTupleStr (tuple, Tuple::Title, ID3_TITLE, dict); + add_frameFromTupleStr (tuple, Tuple::Artist, ID3_ARTIST, dict); + add_frameFromTupleStr (tuple, Tuple::Album, ID3_ALBUM, dict); + add_frameFromTupleStr (tuple, Tuple::AlbumArtist, ID3_ALBUM_ARTIST, dict); + add_frameFromTupleStr (tuple, Tuple::Composer, ID3_COMPOSER, dict); + add_frameFromTupleStr (tuple, Tuple::Copyright, ID3_COPYRIGHT, dict); + add_frameFromTupleInt (tuple, Tuple::Year, ID3_YEAR, dict); + add_frameFromTupleInt (tuple, Tuple::Track, ID3_TRACKNR, dict); + add_frameFromTupleStr (tuple, Tuple::Genre, ID3_GENRE, dict); + + String comment = tuple.get_str (Tuple::Comment); + add_comment_frame (comment, dict); + + /* location and size of non-tag data */ + int64_t mp3_offset = offset ? 0 : header_size + data_size + footer_size; + int64_t mp3_size = offset ? offset : -1; + + auto temp = VFSFile::tmpfile (); + if (! temp) + return false; + + /* write empty header (will be overwritten later) */ + if (! write_header (temp, version, 0)) + return false; + + /* write tag data */ + data_size = write_all_frames (temp, dict, version); + + /* copy non-tag data */ + if (f.fseek (mp3_offset, VFS_SEEK_SET) < 0 || ! temp.copy_from (f, mp3_size)) + return false; + + /* go back to beginning and write real header */ + if (temp.fseek (0, VFS_SEEK_SET) < 0 || ! write_header (temp, version, data_size)) + return false; + + if (! f.replace_with (temp)) + return false; + + return true; +} + +} diff --git a/src/libaudtag/meson.build b/src/libaudtag/meson.build new file mode 100644 index 0000000..c766bdb --- /dev/null +++ b/src/libaudtag/meson.build @@ -0,0 +1,27 @@ +libaudtag_sources = [ + 'audtag.cc', + 'util.cc', + 'tag_module.cc', + 'id3/id3-common.cc', + 'id3/id3v1.cc', + 'id3/id3v22.cc', + 'id3/id3v24.cc', + 'ape/ape.cc' +] + + +libaudtag_inc = include_directories('.') + + +install_headers('audtag.h', subdir: 'audacious') + + +libaudtag_lib = library('audtag', + libaudtag_sources, + include_directories: src_inc, + dependencies: [glib_dep], + link_with: libaudcore_lib, + version: '3.0.0', + soversion: 3, + install: true +) diff --git a/src/libaudtag/tag_module.cc b/src/libaudtag/tag_module.cc new file mode 100644 index 0000000..15110d2 --- /dev/null +++ b/src/libaudtag/tag_module.cc @@ -0,0 +1,92 @@ +/* + * tag_module.c + * Copyright 2009-2011 Paula Stanciu and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include <libaudcore/index.h> +#include <libaudcore/runtime.h> +#include <libaudcore/tuple.h> +#include <libaudcore/vfs.h> + +#include "audtag.h" +#include "util.h" +#include "tag_module.h" +#include "builtin.h" + +namespace audtag { + +static APETagModule ape; +static ID3v1TagModule id3v1; +static ID3v22TagModule id3v22; +static ID3v24TagModule id3v24; + +static TagModule * const modules[] = {& id3v24, & id3v22, & ape, & id3v1}; + +TagModule * find_tag_module (VFSFile & fd, TagType new_type) +{ + for (TagModule * module : modules) + { + if (fd.fseek (0, VFS_SEEK_SET)) + { + AUDDBG("not a seekable file\n"); + return nullptr; + } + + if (module->can_handle_file (fd)) + { + AUDDBG ("Module %s accepted file.\n", module->m_name); + return module; + } + } + + /* No existing tag; see if we can create a new one. */ + if (new_type != TagType::None) + { + for (TagModule * module : modules) + { + if (module->m_type == new_type) + return module; + } + } + + AUDDBG("no module found\n"); + return nullptr; +} + +/************************************************************************************************************** + * tag module object management * + **************************************************************************************************************/ +bool TagModule::can_handle_file (VFSFile & file) +{ + AUDDBG("Module %s does not support %s (no probing function implemented).\n", m_name, + file.filename ()); + return false; +} + +bool TagModule::read_tag (VFSFile & file, Tuple & tuple, Index<char> * image) +{ + AUDDBG ("%s: read_tag() not implemented.\n", m_name); + return false; +} + +bool TagModule::write_tag (VFSFile & file, Tuple const & tuple) +{ + AUDDBG ("%s: write_tag() not implemented.\n", m_name); + return false; +} + +} diff --git a/src/libaudtag/tag_module.h b/src/libaudtag/tag_module.h new file mode 100644 index 0000000..a08effb --- /dev/null +++ b/src/libaudtag/tag_module.h @@ -0,0 +1,46 @@ +/* + * tag_module.h + * Copyright 2009-2011 Paula Stanciu, Tony Vroon, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef TAG_MODULE_H +#define TAG_MODULE_H + +#include "audtag.h" + +namespace audtag { + +struct TagModule +{ + const char * m_name; + TagType m_type; /* set to None if the module cannot create new tags */ + + virtual bool can_handle_file (VFSFile & file); + virtual bool read_tag (VFSFile & file, Tuple & tuple, Index<char> * image); + virtual bool write_tag (VFSFile & file, const Tuple & tuple); + +protected: + constexpr TagModule (const char * name, TagType type) : + m_name (name), + m_type (type) {} +}; + +TagModule * find_tag_module (VFSFile & handle, TagType new_type); + +} + +#endif /* TAG_MODULE_H */ diff --git a/src/libaudtag/util.cc b/src/libaudtag/util.cc new file mode 100644 index 0000000..7b66728 --- /dev/null +++ b/src/libaudtag/util.cc @@ -0,0 +1,175 @@ +/* + * util.c + * Copyright 2009-2014 Paula Stanciu, Tony Vroon, and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#include "util.h" + +const char *convert_numericgenre_to_text(int numericgenre) +{ + static const struct + { + int numericgenre; + const char *genre; + } + table[] = + { + {GENRE_BLUES, "Blues"}, + {GENRE_CLASSIC_ROCK, "Classic Rock"}, + {GENRE_COUNTRY, "Country"}, + {GENRE_DANCE, "Dance"}, + {GENRE_DISCO, "Disco"}, + {GENRE_FUNK, "Funk"}, + {GENRE_GRUNGE, "Grunge"}, + {GENRE_HIPHOP, "Hip-Hop"}, + {GENRE_JAZZ, "Jazz"}, + {GENRE_METAL, "Metal"}, + {GENRE_NEW_AGE, "New Age"}, + {GENRE_OLDIES, "Oldies"}, + {GENRE_OTHER, "Other"}, + {GENRE_POP, "Pop"}, + {GENRE_R_B, "R&B"}, + {GENRE_RAP, "Rap"}, + {GENRE_REGGAE, "Reggae"}, + {GENRE_ROCK, "Rock"}, + {GENRE_TECHNO, "Techno"}, + {GENRE_INDUSTRIAL, "Industrial"}, + {GENRE_ALTERNATIVE, "Alternative"}, + {GENRE_SKA, "Ska"}, + {GENRE_DEATH_METAL, "Death Metal"}, + {GENRE_PRANKS, "Pranks"}, + {GENRE_SOUNDTRACK, "Soundtrack"}, + {GENRE_EURO_TECHNO, "Euro-Techno"}, + {GENRE_AMBIENT, "Ambient"}, + {GENRE_TRIP_HOP, "Trip-Hop"}, + {GENRE_VOCAL, "Vocal"}, + {GENRE_JAZZ_FUNK, "Jazz+Funk"}, + {GENRE_FUSION, "Fusion"}, + {GENRE_TRANCE, "Trance"}, + {GENRE_CLASSICAL, "Classical"}, + {GENRE_INSTRUMENTAL, "Instrumental"}, + {GENRE_ACID, "Acid"}, + {GENRE_HOUSE, "House"}, + {GENRE_GAME, "Game"}, + {GENRE_SOUND_CLIP, "Sound Clip"}, + {GENRE_GOSPEL, "Gospel"}, + {GENRE_NOISE, "Noise"}, + {GENRE_ALTERNROCK, "AlternRock"}, + {GENRE_BASS, "Bass"}, + {GENRE_SOUL, "Soul"}, + {GENRE_PUNK, "Punk"}, + {GENRE_SPACE, "Space"}, + {GENRE_MEDITATIVE, "Meditative"}, + {GENRE_INSTRUMENTAL_POP, "Instrumental Pop"}, + {GENRE_INSTRUMENTAL_ROCK, "Instrumental Rock"}, + {GENRE_ETHNIC, "Ethnic"}, + {GENRE_GOTHIC, "Gothic"}, + {GENRE_DARKWAVE, "Darkwave"}, + {GENRE_TECHNO_INDUSTRIAL, "Techno-Industrial"}, + {GENRE_ELECTRONIC, "Electronic"}, + {GENRE_POP_FOLK, "Pop-Folk"}, + {GENRE_EURODANCE, "Eurodance"}, + {GENRE_DREAM, "Dream"}, + {GENRE_SOUTHERN_ROCK, "Southern Rock"}, + {GENRE_COMEDY, "Comedy"}, + {GENRE_CULT, "Cult"}, + {GENRE_GANGSTA, "Gangsta"}, + {GENRE_TOP40, "Top 40"}, + {GENRE_CHRISTIAN_RAP, "Christian Rap"}, + {GENRE_POP_FUNK, "Pop/Funk"}, + {GENRE_JUNGLE, "Jungle"}, + {GENRE_NATIVE_AMERICAN, "Native American"}, + {GENRE_CABARET, "Cabaret"}, + {GENRE_NEW_WAVE, "New Wave"}, + {GENRE_PSYCHEDELIC, "Psychedelic"}, + {GENRE_RAVE, "Rave"}, + {GENRE_SHOWTUNES, "Showtunes"}, + {GENRE_TRAILER, "Trailer"}, + {GENRE_LO_FI, "Lo-Fi"}, + {GENRE_TRIBAL, "Tribal"}, + {GENRE_ACID_PUNK, "Acid Punk"}, + {GENRE_ACID_JAZZ, "Acid Jazz"}, + {GENRE_POLKA, "Polka"}, + {GENRE_RETRO, "Retro"}, + {GENRE_MUSICAL, "Musical"}, + {GENRE_ROCK_ROLL, "Rock & Roll"}, + {GENRE_HARD_ROCK, "Hard Rock"}, + {GENRE_FOLK, "Folk"}, + {GENRE_FOLK_ROCK, "Folk-Rock"}, + {GENRE_NATIONAL_FOLK, "National Folk"}, + {GENRE_SWING, "Swing"}, + {GENRE_FAST_FUSION, "Fast Fusion"}, + {GENRE_BEBOB, "Bebob"}, + {GENRE_LATIN, "Latin"}, + {GENRE_REVIVAL, "Revival"}, + {GENRE_CELTIC, "Celtic"}, + {GENRE_BLUEGRASS, "Bluegrass"}, + {GENRE_AVANTGARDE, "Avantgarde"}, + {GENRE_GOTHIC_ROCK, "Gothic Rock"}, + {GENRE_PROGRESSIVE_ROCK, "Progressive Rock"}, + {GENRE_PSYCHEDELIC_ROCK, "Psychedelic Rock"}, + {GENRE_SYMPHONIC_ROCK, "Symphonic Rock"}, + {GENRE_SLOW_ROCK, "Slow Rock"}, + {GENRE_BIG_BAND, "Big Band"}, + {GENRE_CHORUS, "Chorus"}, + {GENRE_EASY_LISTENING, "Easy Listening"}, + {GENRE_ACOUSTIC, "Acoustic"}, + {GENRE_HUMOUR, "Humour"}, + {GENRE_SPEECH, "Speech"}, + {GENRE_CHANSON, "Chanson"}, + {GENRE_OPERA, "Opera"}, + {GENRE_CHAMBER_MUSIC, "Chamber Music"}, + {GENRE_SONATA, "Sonata"}, + {GENRE_SYMPHONY, "Symphony"}, + {GENRE_BOOTY_BASS, "Booty Bass"}, + {GENRE_PRIMUS, "Primus"}, + {GENRE_PORN_GROOVE, "Porn Groove"}, + {GENRE_SATIRE, "Satire"}, + {GENRE_SLOW_JAM, "Slow Jam"}, + {GENRE_CLUB, "Club"}, + {GENRE_TANGO, "Tango"}, + {GENRE_SAMBA, "Samba"}, + {GENRE_FOLKLORE, "Folklore"}, + {GENRE_BALLAD, "Ballad"}, + {GENRE_POWER_BALLAD, "Power Ballad"}, + {GENRE_RHYTHMIC_SOUL, "Rhythmic Soul"}, + {GENRE_FREESTYLE, "Freestyle"}, + {GENRE_DUET, "Duet"}, + {GENRE_PUNK_ROCK, "Punk Rock"}, + {GENRE_DRUM_SOLO, "Drum Solo"}, + {GENRE_A_CAPELLA, "A capella"}, + {GENRE_EURO_HOUSE, "Euro-House"}, + }; + + for (auto & pair : table) + { + if (pair.numericgenre == numericgenre) + return pair.genre; + } + + return nullptr; +} + +uint32_t unsyncsafe32 (uint32_t x) +{ + return (x & 0x7f) | ((x & 0x7f00) >> 1) | ((x & 0x7f0000) >> 2) | ((x & 0x7f000000) >> 3); +} + +uint32_t syncsafe32 (uint32_t x) +{ + return (x & 0x7f) | ((x & 0x3f80) << 1) | ((x & 0x1fc000) << 2) | ((x & 0xfe00000) << 3); +} diff --git a/src/libaudtag/util.h b/src/libaudtag/util.h new file mode 100644 index 0000000..9d9f03e --- /dev/null +++ b/src/libaudtag/util.h @@ -0,0 +1,158 @@ +/* + * util.h + * Copyright 2009-2010 Paula Stanciu and John Lindgren + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions, and the following disclaimer in the documentation + * provided with the distribution. + * + * This software is provided "as is" and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising from + * the use of this software. + */ + +#ifndef TAGUTIL_H +#define TAGUTIL_H + +#include <stdint.h> + +enum { + GENRE_BLUES = 0, + GENRE_CLASSIC_ROCK, + GENRE_COUNTRY, + GENRE_DANCE, + GENRE_DISCO, + GENRE_FUNK, + GENRE_GRUNGE, + GENRE_HIPHOP, + GENRE_JAZZ, + GENRE_METAL, + GENRE_NEW_AGE, + GENRE_OLDIES, + GENRE_OTHER, + GENRE_POP, + GENRE_R_B, + GENRE_RAP, + GENRE_REGGAE, + GENRE_ROCK, + GENRE_TECHNO, + GENRE_INDUSTRIAL, + GENRE_ALTERNATIVE, + GENRE_SKA, + GENRE_DEATH_METAL, + GENRE_PRANKS, + GENRE_SOUNDTRACK, + GENRE_EURO_TECHNO, + GENRE_AMBIENT, + GENRE_TRIP_HOP, + GENRE_VOCAL, + GENRE_JAZZ_FUNK, + GENRE_FUSION, + GENRE_TRANCE, + GENRE_CLASSICAL, + GENRE_INSTRUMENTAL, + GENRE_ACID, + GENRE_HOUSE, + GENRE_GAME, + GENRE_SOUND_CLIP, + GENRE_GOSPEL, + GENRE_NOISE, + GENRE_ALTERNROCK, + GENRE_BASS, + GENRE_SOUL, + GENRE_PUNK, + GENRE_SPACE, + GENRE_MEDITATIVE, + GENRE_INSTRUMENTAL_POP, + GENRE_INSTRUMENTAL_ROCK, + GENRE_ETHNIC, + GENRE_GOTHIC, + GENRE_DARKWAVE, + GENRE_TECHNO_INDUSTRIAL, + GENRE_ELECTRONIC, + GENRE_POP_FOLK, + GENRE_EURODANCE, + GENRE_DREAM, + GENRE_SOUTHERN_ROCK, + GENRE_COMEDY, + GENRE_CULT, + GENRE_GANGSTA, + GENRE_TOP40, + GENRE_CHRISTIAN_RAP, + GENRE_POP_FUNK, + GENRE_JUNGLE, + GENRE_NATIVE_AMERICAN, + GENRE_CABARET, + GENRE_NEW_WAVE, + GENRE_PSYCHEDELIC, + GENRE_RAVE, + GENRE_SHOWTUNES, + GENRE_TRAILER, + GENRE_LO_FI, + GENRE_TRIBAL, + GENRE_ACID_PUNK, + GENRE_ACID_JAZZ, + GENRE_POLKA, + GENRE_RETRO, + GENRE_MUSICAL, + GENRE_ROCK_ROLL, + GENRE_HARD_ROCK, + GENRE_FOLK, + GENRE_FOLK_ROCK, + GENRE_NATIONAL_FOLK, + GENRE_SWING, + GENRE_FAST_FUSION, + GENRE_BEBOB, + GENRE_LATIN, + GENRE_REVIVAL, + GENRE_CELTIC, + GENRE_BLUEGRASS, + GENRE_AVANTGARDE, + GENRE_GOTHIC_ROCK, + GENRE_PROGRESSIVE_ROCK, + GENRE_PSYCHEDELIC_ROCK, + GENRE_SYMPHONIC_ROCK, + GENRE_SLOW_ROCK, + GENRE_BIG_BAND, + GENRE_CHORUS, + GENRE_EASY_LISTENING, + GENRE_ACOUSTIC, + GENRE_HUMOUR, + GENRE_SPEECH, + GENRE_CHANSON, + GENRE_OPERA, + GENRE_CHAMBER_MUSIC, + GENRE_SONATA, + GENRE_SYMPHONY, + GENRE_BOOTY_BASS, + GENRE_PRIMUS, + GENRE_PORN_GROOVE, + GENRE_SATIRE, + GENRE_SLOW_JAM, + GENRE_CLUB, + GENRE_TANGO, + GENRE_SAMBA, + GENRE_FOLKLORE, + GENRE_BALLAD, + GENRE_POWER_BALLAD, + GENRE_RHYTHMIC_SOUL, + GENRE_FREESTYLE, + GENRE_DUET, + GENRE_PUNK_ROCK, + GENRE_DRUM_SOLO, + GENRE_A_CAPELLA, + GENRE_EURO_HOUSE +}; + +const char *convert_numericgenre_to_text(int numericgenre); + +uint32_t unsyncsafe32 (uint32_t x); +uint32_t syncsafe32 (uint32_t x); + +#endif /* TAGUTIL_H */ diff --git a/src/libguess/Makefile b/src/libguess/Makefile new file mode 100644 index 0000000..0a2ca3d --- /dev/null +++ b/src/libguess/Makefile @@ -0,0 +1,12 @@ +STATIC_LIB_NOINST = libguess.a + +SRCS = dfa.c \ + guess.c \ + guess_impl.c + +include ../../buildsys.mk +include ../../extra.mk + +CPPFLAGS := -I../.. ${CPPFLAGS} -DLIBGUESS_CORE + +CFLAGS += ${LIB_CFLAGS} -Wno-unused-variable diff --git a/src/libguess/dfa.c b/src/libguess/dfa.c new file mode 100644 index 0000000..a7d5943 --- /dev/null +++ b/src/libguess/dfa.c @@ -0,0 +1,62 @@ +#include "libguess.h" +#include "dfa.h" + +boolean +dfa_alone(guess_dfa *dfa, guess_dfa *order[]) +{ + int i; + + if (dfa->state < 0) + return FALSE; + + for (i = 0; order[i] != NULL; i++) { + if (order[i] != dfa && order[i]->state >= 0) { //DFA_ALIVE() + return FALSE; + } + } + + return TRUE; +} + +boolean +dfa_none(guess_dfa *order[]) +{ + int i; + + for (i = 0; order[i] != NULL; i++) { + if (order[i]->state >= 0) { //DFA_ALIVE() + return FALSE; + } + } + + return TRUE; +} + +guess_dfa * +dfa_top(guess_dfa *order[]) +{ + int i; + guess_dfa *top = NULL; + for (i = 0; order[i] != NULL; i++) { + if (order[i]->state >= 0) { //DFA_ALIVE() + if (top == NULL || order[i]->score > top->score) + top = order[i]; + } + } + return top; +} + +const char * +dfa_process(guess_dfa *order[], int c) +{ + int i; + for (i = 0; order[i] != NULL; i++) { + if (DFA_ALIVE_P(order[i])) { + if (dfa_alone(order[i], order)) + return order[i]->name; + DFA_NEXT_P(order[i], c); + } + } + + return NULL; +} diff --git a/src/libguess/dfa.h b/src/libguess/dfa.h new file mode 100644 index 0000000..122db0c --- /dev/null +++ b/src/libguess/dfa.h @@ -0,0 +1,79 @@ +#ifndef __DFA_H__ +#define __DFA_H__ + +typedef int boolean; +#define TRUE 1 +#define FALSE 0 + +/* workaround for that glib's g_convert can't convert + properly from UCS-2BE/LE trailing after BOM. */ +#define WITH_G_CONVERT 1 +/* #undef WITH_G_CONVERT */ + +#ifdef WITH_G_CONVERT +#define UCS_2BE "UTF-16" +#define UCS_2LE "UTF-16" +#else +#define UCS_2BE "UCS_2BE" +#define UCS_2LE "UCS_2LE" +#endif + +/* data types */ +typedef struct guess_arc_rec +{ + unsigned int next; /* next state */ + double score; /* score */ +} guess_arc; + +typedef struct guess_dfa_rec +{ + signed char (*states)[256]; + guess_arc *arcs; + int state; + double score; + char *name; +} guess_dfa; + +/* macros */ +#define DFA_INIT(st, ar, name) \ + { st, ar, 0, 1.0 ,name} + +#define DFA_NEXT(dfa, ch) \ + do { \ + int arc__; \ + if (dfa.state >= 0) { \ + arc__ = dfa.states[dfa.state][ch]; \ + if (arc__ < 0) { \ + dfa.state = -1; \ + } else { \ + dfa.state = dfa.arcs[arc__].next; \ + dfa.score *= dfa.arcs[arc__].score; \ + } \ + } \ + } while (0) + +#define DFA_ALIVE(dfa) (dfa.state >= 0) + +#define DFA_NEXT_P(dfa, ch) \ + do { \ + int arc__; \ + if (dfa->state >= 0) { \ + arc__ = dfa->states[dfa->state][ch]; \ + if (arc__ < 0) { \ + dfa->state = -1; \ + } else { \ + dfa->state = dfa->arcs[arc__].next; \ + dfa->score *= dfa->arcs[arc__].score; \ + } \ + } \ + } while (0) + +#define DFA_ALIVE_P(dfa) (dfa->state >= 0) + +/* prototypes */ +boolean dfa_alone(guess_dfa *dfa, guess_dfa *order[]); +boolean dfa_none(guess_dfa *order[]); +guess_dfa *dfa_top(guess_dfa *order[]); +const char *dfa_process(guess_dfa *order[], int c); + +#endif diff --git a/src/libguess/guess.c b/src/libguess/guess.c new file mode 100644 index 0000000..6bb8f7a --- /dev/null +++ b/src/libguess/guess.c @@ -0,0 +1,54 @@ +#include <stdlib.h> +#include <strings.h> + +#include "libguess.h" + +struct guess_impl { + const char *lang; + guess_impl_f impl; +}; + +/* keep these in alphabetical order! */ +static const struct guess_impl guess_impl_list[] = { + {"arabic", guess_ar}, + {"baltic", guess_bl}, + {"chinese", guess_cn}, + {"greek", guess_gr}, + {"hebrew", guess_hw}, + {"japanese", guess_jp}, + {"korean", guess_kr}, + {"polish", guess_pl}, + {"russian", guess_ru}, + {"taiwanese", guess_tw}, + {"turkish", guess_tr}, +}; + +static int +guess_cmp_impl(const void *key, const void *ptr) +{ + const struct guess_impl *impl = ptr; + return strcasecmp(key, impl->lang); +} + +static guess_impl_f +guess_find_impl(const char *lang) +{ + struct guess_impl *impl = + bsearch(lang, guess_impl_list, + sizeof guess_impl_list / sizeof(struct guess_impl), + sizeof(struct guess_impl), guess_cmp_impl); + + return (impl != NULL) ? impl->impl : NULL; +} + +const char * +libguess_determine_encoding(const char *inbuf, int buflen, const char *lang) +{ + guess_impl_f impl = guess_find_impl(lang); + + if (impl != NULL) + return impl(inbuf, buflen); + + /* TODO: try other languages as fallback? */ + return NULL; +} diff --git a/src/libguess/guess.scm b/src/libguess/guess.scm new file mode 100644 index 0000000..7e228be --- /dev/null +++ b/src/libguess/guess.scm @@ -0,0 +1,623 @@ +;;; +;;; This code is derivative of guess.c of Gauche-0.8.7. +;;; The following is the original copyright notice. +;;; + +;;; +;;; Auxiliary script to generate japanese code guessing table +;;; +;;; Copyright (c) 2000-2003 Shiro Kawai, All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions +;;; are met: +;;; +;;; 1. Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; +;;; 2. Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; +;;; 3. Neither the name of the authors nor the names of its contributors +;;; may be used to endorse or promote products derived from this +;;; software without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +;;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +;;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +;;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +;;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +;;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +;;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +;;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +;;; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;;; +;;; $Id: guess.scm,v 1.3 2003/07/05 03:29:10 shirok Exp $ +;;; + +;;; +;;; To rebuild DFA tables, install Gauche and run the following in +;;; the libguess source directory: +;;; +;;; $ gosh guess.scm guess_tab.c +;;; +;;; DFAs are defined such as: +;;; +;;; (define-dfa c-prefix-name +;;; (init +;;; (((byte sequence)) step-name confidence-score) +;;; (((byte sequence)) step-name confidence-score))) +;;; +;;; DFAs can have infinite steps, the table defines how the DFA behaves. +;;; 'init' is the name of the first step. +;;; + +(use srfi-1) +(use gauche.sequence) + +;; This is a simple state machine compiler. +;; +;; <state-machine> : (define-dfa <name> <state> ...) +;; <state> : (<name> (<input-set> <next-state> <score>) ...) +;; <name> : symbol +;; <next-state> : symbol +;; <score> : real +;; <input-set> : (<byte-or-range> ...) +;; <byte-or-range> : <byte> | (<byte> <byte>) +;; <byte> : integer between 0 and #xff | ASCII char +;; +;; When evaluated, the DFA generates a state transition table in +;; C source format. + +(define-class <dfa> () + ((name :init-keyword :name :accessor name-of) + (states :init-keyword :states :accessor states-of) + (instances :allocation :class :init-value '()))) + +(define-class <state> () + ((name :init-keyword :name :accessor name-of) + (index :init-keyword :index :accessor index-of) + (arcs :init-keyword :arcs :accessor arcs-of :init-value '()))) + +(define-class <arc> () + ((from-state :init-keyword :from-state :accessor from-state-of) + (to-state :init-keyword :to-state :accessor to-state-of) + (ranges :init-keyword :ranges :accessor ranges-of) + (index :init-keyword :index :accessor index-of) + (score :init-keyword :score :accessor score-of))) + +;; Create DFA + +(define-syntax define-dfa + (syntax-rules () + ((_ name . states) + (define name (make <dfa> + :name 'name + :states (resolve-states 'states)))))) + +(define-method initialize ((self <dfa>) initargs) + (next-method) + (slot-push! self 'instances self)) + +(define (all-dfas) (reverse (class-slot-ref <dfa> 'instances))) + +(define (resolve-states state-defs) + (let ((states (map (lambda (d i) (make <state> :name (car d) :index i)) + state-defs + (iota (length state-defs))))) + (fold (lambda (s d i) + (let1 num-arcs (length (cdr d)) + (set! (arcs-of s) + (map (lambda (arc aindex) + (make <arc> + :from-state s + :to-state (or (find (lambda (e) + (eq? (name-of e) (cadr arc))) + states) + (error "no such state" (cadr arc))) + :ranges (car arc) + :index aindex + :score (caddr arc))) + (cdr d) + (iota num-arcs i))) + (+ i num-arcs))) + 0 + states state-defs) + states)) + +;; Emit state table +(define (emit-dfa-table dfa) + (format #t "static signed char guess_~a_st[][256] = {\n" (name-of dfa)) + (for-each emit-state-table (states-of dfa)) + (print "};\n") + (format #t "static guess_arc guess_~a_ar[] = {\n" (name-of dfa)) + (for-each emit-arc-table + (append-map arcs-of (states-of dfa))) + (print "};\n") + ) + +(define (emit-state-table state) + (define (b2i byte) ;byte->integer + (if (char? byte) (char->integer byte) byte)) + (let1 arc-vec (make-vector 256 -1) + (dolist (br (arcs-of state)) + (dolist (range (ranges-of br)) + (if (pair? range) + (vector-fill! arc-vec (index-of br) + (b2i (car range)) (+ (b2i (cadr range)) 1)) + (set! (ref arc-vec (b2i range)) (index-of br))))) + (format #t " { /* state ~a */" (name-of state)) + (dotimes (i 256) + (when (zero? (modulo i 16)) (newline)) + (format #t " ~2d," (ref arc-vec i))) + (print "\n },") + )) + +(define (emit-arc-table arc) + (format #t " { ~2d, ~5s }, /* ~a -> ~a */\n" + (index-of (to-state-of arc)) + (score-of arc) + (name-of (from-state-of arc)) + (name-of (to-state-of arc)))) +;; +;; main +;; + +(define (main args) + (unless (= (length args) 2) + (error (format #f "usage: ~a <output-file.c>" (car args)))) + (with-output-to-file (cadr args) + (lambda () + (print "/* State transition table for character code guessing */") + (print "/* This file is automatically generated by guess.scm */") + (print "") + (print "#include \"dfa.h\"") + (newline) + (for-each emit-dfa-table (all-dfas)))) + 0) + +;;;============================================================ +;;; DFA definitions +;;; + +;;; +;;; EUC-JP +;;; + +(define-dfa eucj + ;; first byte + (init + (((#x00 #x7f)) init 1.0) ; ASCII range + ((#x8e) jis0201_kana 0.8) ; JISX 0201 kana + ((#x8f) jis0213_2 0.95) ; JISX 0213 plane 2 + (((#xa1 #xfe)) jis0213_1 1.0)) ; JISX 0213 plane 1 + ;; jis x 0201 kana + (jis0201_kana + (((#xa1 #xdf)) init 1.0)) + ;; jis x 0208 and jis x 0213 plane 1 + (jis0213_1 + (((#xa1 #xfe)) init 1.0)) + ;; jis x 0213 plane 2 + (jis0213_2 + (((#xa1 #xfe)) init 1.0))) + +;;; +;;; Shift_JIS +;;; + +(define-dfa sjis + ;; first byte + (init + (((#x00 #x7f)) init 1.0) ;ascii + (((#x81 #x9f) (#xe1 #xef)) jis0213 1.0) ;jisx0213 plane 1 + (((#xa1 #xdf)) init 0.8) ;jisx0201 kana + (((#xf0 #xfc)) jis0213 0.95) ;jisx0213 plane 2 + (((#xfd #xff)) init 0.8)) ;vendor extension + (jis0213 + (((#x40 #x7e) (#x80 #xfc)) init 1.0))) + +;;; +;;; UTF-8 +;;; + +(define-dfa utf8 + (init + (((#x00 #x7f)) init 1.0) + (((#xc2 #xdf)) 1byte_more 1.0) + (((#xe0 #xe0)) 2byte_more1 1.0) + (((#xe1 #xec)) 2byte_more2 1.0) + (((#xed #xed)) 2byte_more3 1.0) + (((#xee #xef)) 2byte_more2 1.0) + (((#xf0 #xf0)) 3byte_more1 1.0) + (((#xf1 #xf3)) 3byte_more2 1.0) + (((#xf4 #xf4)) 3byte_more3 1.0)) + (1byte_more + (((#x80 #xbf)) init 1.0)) + (2byte_more1 + (((#xa0 #xbf)) 1byte_more 1.0)) + (2byte_more2 + (((#x80 #xbf)) 1byte_more 1.0)) + (2byte_more3 + (((#x80 #x9f)) 1byte_more 1.0)) + (3byte_more1 + (((#x90 #xbf)) 2byte_more2 1.0)) + (3byte_more2 + (((#x80 #xbf)) 2byte_more2 1.0)) + (3byte_more3 + (((#x80 #x8f)) 2byte_more2 1.0))) + +;;; +;;; UCS-2LE +;;; +(define-dfa ucs2le + (init + ((#xfe) bom-be 1.0) + ((#xff) bom-le 1.0) + (((#x00 #xfd)) byte2 1.0)) + (bom-le + (((#x00 #xff)) init 1.0)) + (bom-be + (((#x00 #xfe)) init 1.0)) ;; if be (0xfeff), die. + (byte2 + (((#x00 #xff)) init 1.0))) + +;;; +;;; UCS-2BE +;;; +(define-dfa ucs2be + (init + ((#xfe) bom-be 1.0) + ((#xff) bom-le 1.0) + (((#x00 #xfd)) byte2 1.0)) + (bom-le + (((#x00 #xfd)) init 1.0) + ((#xff) init 1.0)) ;; if le (0xfffe), die. + (bom-be + (((#x00 #xff)) init 1.0)) + (byte2 + (((#x00 #xff)) init 1.0))) + +;;; +;;; UTF-16 +;;; +(define-dfa utf16 + (init + ((#xfe) bom-be 1.0) + ((#xff) bom-le 1.0)) + (init1 + (((#x00 #xff)) byte2 1.0)) + (bom-be + ((#xff) init1 1.0)) + (bom-le + ((#xfe) init1 1.0)) + (byte2 + (((#x00 #xff)) init1 1.0))) + +;;; +;;; ISO2022JP (JIS) +;;; + +;; NB: for now, we just check the sequence of <ESC> $ or <ESC> '('. +'(define-dfa jis + (init + ((#x1b) esc 1.0) + (((#x00 #x1a) (#x1c #x1f)) init 1.0) ;C0 + (((#x20 #x7f)) init 1.0) ;ASCII + (((#xa1 #xdf)) init 0.7)) ;JIS8bit kana + (esc + ((#x0d #x0a) init 0.9) ;cancel + ((#\( ) esc-paren 1.0) + ((#\$ ) esc-$ 1.0) + ((#\& ) esc-& 1.0)) + (esc-paren + ((#\B #\J #\H) init 1.0) + ((#\I) jis0201kana 0.8)) + (esc-$ + ((#\@ #\B) kanji 1.0) + ((#\( ) esc-$-paren 1.0)) + (esc-$-paren + ((#\D #\O #\P) kanji 1.0)) + (esc-& + ((#\@ ) init 1.0)) + (jis0201kana + ((#x1b) esc 1.0) + (((#x20 #x5f)) jis0201kana 1.0)) + (kanji + ((#x1b) esc 1.0) + (((#x21 #x7e)) kanji-2 1.0)) + (kanji-2 + (((#x21 #x7e)) kanji 1.0)) ) + +;;; +;;; Big5 +;;; + +(define-dfa big5 + ;; first byte + (init + (((#x00 #x7f)) init 1.0) ;ascii + (((#xa1 #xfe)) 2byte 1.0)) ;big5-2byte + (2byte + (((#x40 #x7e) (#xa1 #xfe)) init 1.0))) + +;;; +;;; GB2312 (EUC-CN?) +;;; + +(define-dfa gb2312 + ;; first byte + (init + (((#x00 #x7f)) init 1.0) ;ascii + (((#xa1 #xfe)) 2byte 1.0)) ;gb2312 2byte + (2byte + (((#xa1 #xfe)) init 1.0))) + +;;; +;;; GB18030 +;;; + +(define-dfa gb18030 + ;; first byte + (init + (((#x00 #x80)) init 1.0) ;ascii + (((#x81 #xfe)) 2byte 1.0) ;gb18030 2byte + (((#x81 #xfe)) 4byte2 1.0)) ;gb18030 2byte + (2byte + (((#x40 #x7e) (#x80 #xfe)) init 1.0)) + (4byte2 + (((#x30 #x39)) 4byte3 1.0)) + (4byte3 + (((#x81 #xfe)) 4byte4 1.0)) + (4byte4 + (((#x30 #x39)) init 1.0)) ) + +;;; +;;; EUC-KR +;;; + +(define-dfa euck + ;; first byte + (init + (((#x00 #x7f)) init 1.0) ; ASCII range + (((#xa1 #xfe)) ks1001 1.0)) ; KSX 1001 + ;; ks x 1001 + (ks1001 + (((#xa1 #xfe)) init 1.0))) + +;;; +;;; Johab +;;; + +(define-dfa johab + ;; first byte + (init + (((#x00 #x7f)) init 1.0) ; ASCII range + (((#x84 #xd3)) jamo51 1.0) ; jamo51 + (((#xd8 #xde) (#xe0 #xf9)) jamo42 0.95)) ; jamo42 + ;; second byte + (jamo51 + (((#x41 #x7e) (#x81 #xfe)) init 1.0)) + (jamo42 + (((#x31 #x7e) (#x91 #xfe)) init 1.0))) + + + + + + +;;; +;;; arabic +;;; + +(define-dfa iso8859_6 + (init + (((#x00 #x7f)) init 1.0) ;ascii + ((#xa0) init 1.0) + ((#xa4) init 1.0) + ((#xac) init 1.0) + ((#xad) init 1.0) ;SHY xxx + ((#xbb) init 1.0) + ((#xbf) init 1.0) + (((#xc1 #xda)) init 1.0) + (((#xe0 #xf2)) init 1.0))) + +(define-dfa cp1256 + (init + (((#x00 #x7f)) init 1.0) ;ascii + (((#x80 #xff)) init 1.0))) ;high bit + + +;;; +;;; greek +;;; + +(define-dfa iso8859_7 + (init + (((#x00 #x7f)) init 1.0) ;ascii + (((#xa0 #xad)) init 1.0) + (((#xaf #xd1)) init 1.0) + (((#xd3 #xfe)) init 1.0))) + +(define-dfa cp1253 + (init + (((#x00 #x7f)) init 1.0) ;ascii + ((#x80) init 1.0) + (((#x82 #x87)) init 1.0) + ((#x89) init 1.0) + ((#x8b) init 1.0) + (((#x91 #x97)) init 1.0) + ((#x99) init 1.0) + ((#x9b) init 1.0) + (((#xa0 #xa9)) init 1.0) + (((#xab #xd1)) init 1.0) + (((#xd3 #xfe)) init 1.0))) + +;;; +;;; hebrew +;;; + +(define-dfa iso8859_8 + (init + (((#x00 #x7f)) init 1.0) ;ascii + ((#xa0) init 1.0) + (((#xa2 #xbe)) init 1.0) + (((#xdf #xfa)) init 1.0) + (((#xfd #xfe)) init 1.0))) + +(define-dfa cp1255 + (init + (((#x00 #x7f)) init 1.0) ;ascii + ((#x80) init 1.0) + (((#x82 #x89)) init 1.0) + ((#x8b) init 1.0) + (((#x91 #x99)) init 1.0) + ((#x9b) init 1.0) + (((#xa0 #xc9)) init 1.0) + (((#xcb #xd8)) init 1.0) + (((#xe0 #xfa)) init 1.0) + (((#xfd #xfe)) init 1.0))) + +;;; +;;; turkish +;;; + +(define-dfa iso8859_9 + (init + (((#x00 #x7f)) init 1.0) ;ascii + (((#xa0 #xff)) init 1.0))) + +(define-dfa cp1254 + (init + (((#x00 #x7f)) init 1.0) ;ascii + ((#x80) init 1.0) + (((#x82 #x8c)) init 1.0) + (((#x91 #x9c)) init 1.0) + (((#x9f #xff)) init 1.0))) + +;;; +;;; russian +;;; + +(define-dfa iso8859_5 + (init + (((#x00 #x7f)) init 1.0) ; ascii + (((#xa0 #xff)) init 1.0))) + +(define-dfa koi8_r + (init + (((#x20 #x7f)) init 1.0) ; ascii + ((#xa3) init 1.0) + ((#xb3) init 1.0) + (((#xc0 #xff)) init 1.0))) + +(define-dfa koi8_u + (init + (((#x20 #x7f)) init 1.0) ; ascii + (((#xa3 #xa4)) init 1.0) + (((#xa6 #xa7)) init 1.0) + ((#xad) init 1.0) + (((#xb3 #xb4)) init 1.0) + (((#xb6 #xb7)) init 1.0) + ((#xbd) init 1.0) + (((#xc0 #xff)) init 1.0))) + +(define-dfa cp866 + (init + (((#x00 #x7f)) init 1.0) ; ascii + (((#x80 #xaf)) init 1.0) + (((#xe0 #xf7)) init 1.0))) + +(define-dfa cp1251 + (init + (((#x00 #x7f)) init 1.0) ; ascii + (((#x80 #x81)) init 1.0) + ((#x83) init 1.0) + ((#x8a) init 1.0) + (((#x8c #x90)) init 1.0) + ((#x9a) init 1.0) + (((#x9c #xa3)) init 1.0) + ((#xa5) init 1.0) + ((#xa8) init 1.0) + ((#xaa) init 1.0) + ((#xaf) init 1.0) + (((#xb2 #xb4)) init 1.0) + ((#xb8) init 1.0) + ((#xba) init 1.0) + (((#xbc #xff)) init 1.0))) + +;;; +;;; polish +;;; + +(define-dfa iso8859_2 + (init + (((#x20 #x7e)) init 1.0) + ((#xa1) init 1.0) + ((#xa3) init 1.0) + (((#xa5 #xa6)) init 1.0) + (((#xa9 #xac)) init 1.0) + (((#xae #xaf)) init 1.0) + ((#xb1) init 1.0) + ((#xb3) init 1.0) + (((#xb5 #xb6)) init 1.0) + (((#xb9 #xbc)) init 1.0) + (((#xbe #xbf)) init 1.0) + (((#xc0 #xd6)) init 1.0) + (((#xd8 #xf6)) init 1.0) + (((#xf8 #xfe)) init 1.0))) + +(define-dfa cp1250 + (init + (((#x20 #x7e)) init 1.0) + (((#x8a #x8f)) init 1.0) + ((#x9a) init 1.0) + (((#x9c #xa1)) init 1.0) + ((#xa3) init 1.0) + ((#xa5) init 1.0) + ((#xaa) init 1.0) + ((#xaf) init 1.0) + ((#xb3) init 1.0) + (((#xb9 #xba)) init 1.0) + ((#xbc) init 1.0) + (((#xbe #xbf)) init 1.0) + (((#xc0 #xd6)) init 1.0) + (((#xd8 #xf6)) init 1.0) + (((#xf8 #xfe)) init 1.0))) + +;;; +;;; baltic (estonia/latvia/lithuania) +;;; + +(define-dfa iso8859_13 + (init + (((#x20 #x7e)) init 1.0) + ((#xa8) init 1.0) + ((#xaa) init 1.0) + ((#xaf) init 1.0) + ((#xb8) init 1.0) + ((#xba) init 1.0) + ((#xbf) init 1.0) + (((#xc0 #xd6)) init 1.0) + (((#xd8 #xf6)) init 1.0) + (((#xf8 #xfe)) init 1.0))) + +(define-dfa cp1257 + (init + (((#x20 #x7e)) init 1.0) + ((#x80) init 1.0) + ((#x82) init 1.0) + (((#x84 #x87)) init 1.0) + ((#x89) init 1.0) + ((#x8b) init 1.0) + (((#x8d #x8f)) init 1.0) + (((#x91 #x97)) init 1.0) + ((#x99) init 1.0) + ((#x9b) init 1.0) + (((#x9d #x9e)) init 1.0) + ((#xa0) init 1.0) + (((#xa2 #xa4)) init 1.0) + (((#xa6 #xff)) init 1.0))) + diff --git a/src/libguess/guess_impl.c b/src/libguess/guess_impl.c new file mode 100644 index 0000000..0a1b83f --- /dev/null +++ b/src/libguess/guess_impl.c @@ -0,0 +1,656 @@ +/* + * This code is derivative of guess.c of Gauche-0.8.3. + * The following is the original copyright notice. + */ + +/* + * guess.c - guessing character encoding + * + * Copyright (c) 2000-2003 Shiro Kawai, All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the authors nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "libguess.h" +#include "dfa.h" + +#include <stdio.h> + +/* take precedence if scores are same. you can customize the order as: */ +/* ORDER_** &highest, &second, ... &lowest */ +#define ORDER_JP &utf8, &sjis, &eucj +#define ORDER_TW &utf8, &big5 +#define ORDER_CN &utf8, &gb2312, &gb18030 +#define ORDER_KR &utf8, &euck, &johab +#define ORDER_AR &utf8, &iso8859_6, &cp1256 +#define ORDER_GR &utf8, &iso8859_7, &cp1253 +#define ORDER_RU &utf8, &cp1251, &koi8_u, &koi8_r, &cp866, &iso8859_2, &iso8859_5 +#define ORDER_HW &utf8, &iso8859_8, &cp1255 +#define ORDER_PL &utf8, &cp1250, &iso8859_2 +#define ORDER_TR &utf8, &iso8859_9, &cp1254 +#define ORDER_BL &utf8, &iso8859_13, &cp1257 + +/* include DFA table generated by guess.scm */ +#include "guess_tab.c" + +int libguess_validate_utf8(const char *buf, int buflen) +{ + int i; + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + + if (DFA_ALIVE(utf8)) + DFA_NEXT(utf8, c); + else + break; + } + + DFA_NEXT(utf8, '\0'); //Bug #53 + + if(DFA_ALIVE(utf8)) + return 1; + else + return 0; +} + +const char *guess_jp(const char *buf, int buflen) +{ + int i; + const char *rv = NULL; + guess_dfa eucj = DFA_INIT(guess_eucj_st, guess_eucj_ar, "EUC-JP"); + guess_dfa sjis = DFA_INIT(guess_sjis_st, guess_sjis_ar, "SJIS"); + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + guess_dfa *top = NULL; + + guess_dfa *order[] = { ORDER_JP, NULL }; + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + + /* special treatment of iso-2022 escape sequence */ + if (c == 0x1b) { + if (i < buflen - 1) { + c = (unsigned char) buf[++i]; + if (c == '$' || c == '(') + return "ISO-2022-JP"; + } + } + + /* special treatment of BOM */ + if (i == 0 && c == 0xff) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xfe) + return UCS_2LE; + } + } + if (i == 0 && c == 0xfe) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xff) + return UCS_2BE; + } + } + + rv = dfa_process(order, c); + if(rv) + return rv; + + if (dfa_none(order)) { + /* we ran out the possibilities */ + return NULL; + } + } + + top = dfa_top(order); + if(top) + return top->name; + else + return NULL; +} + +const char *guess_tw(const char *buf, int buflen) +{ + int i; + const char *rv = NULL; + guess_dfa big5 = DFA_INIT(guess_big5_st, guess_big5_ar, "BIG5"); + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + guess_dfa *top = NULL; + + guess_dfa *order[] = { ORDER_TW, NULL }; + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + + /* special treatment of iso-2022 escape sequence */ + if (c == 0x1b) { + if (i < buflen - 1) { + c = (unsigned char) buf[++i]; + if (c == '$' || c == '(') + return "ISO-2022-TW"; + } + } + + /* special treatment of BOM */ + if (i == 0 && c == 0xff) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xfe) + return UCS_2LE; + } + } + if (i == 0 && c == 0xfe) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xff) + return UCS_2BE; + } + } + + rv = dfa_process(order, c); + if(rv) + return rv; + + if (dfa_none(order)) { + /* we ran out the possibilities */ + return NULL; + } + } + + top = dfa_top(order); + if (top) + return top->name; + else + return NULL; +} + +const char *guess_cn(const char *buf, int buflen) +{ + int i; + const char *rv = NULL; + guess_dfa gb2312 = DFA_INIT(guess_gb2312_st, guess_gb2312_ar, "GB2312"); + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + guess_dfa gb18030 = DFA_INIT(guess_gb18030_st, guess_gb18030_ar, "GB18030"); + guess_dfa *top = NULL; + + guess_dfa *order[] = { ORDER_CN, NULL }; + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + int c2; + + /* special treatment of iso-2022 escape sequence */ + if (c == 0x1b) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + c2 = (unsigned char) buf[i + 2]; + if (c == '$' && (c2 == ')' || c2 == '+')) + return "ISO-2022-CN"; + } + } + + /* special treatment of BOM */ + if (i == 0 && c == 0xff) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xfe) + return UCS_2LE; + } + } + if (i == 0 && c == 0xfe) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xff) + return UCS_2BE; + } + } + + rv = dfa_process(order, c); + if(rv) + return rv; + + if (dfa_none(order)) { + /* we ran out the possibilities */ + return NULL; + } + } + + top = dfa_top(order); + if(top) + return top->name; + else + return NULL; +} + +const char *guess_kr(const char *buf, int buflen) +{ + int i; + const char *rv = NULL; + guess_dfa euck = DFA_INIT(guess_euck_st, guess_euck_ar, "EUC-KR"); + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + guess_dfa johab = DFA_INIT(guess_johab_st, guess_johab_ar, "JOHAB"); + guess_dfa *top = NULL; + + guess_dfa *order[] = { ORDER_KR, NULL }; + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + int c2; + + /* special treatment of iso-2022 escape sequence */ + if (c == 0x1b) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + c2 = (unsigned char) buf[i + 2]; + if (c == '$' && c2 == ')') + return "ISO-2022-KR"; + } + } + + /* special treatment of BOM */ + if (i == 0 && c == 0xff) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xfe) + return UCS_2LE; + } + } + if (i == 0 && c == 0xfe) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xff) + return UCS_2BE; + } + } + + rv = dfa_process(order, c); + if(rv) + return rv; + + if (dfa_none(order)) { + /* we ran out the possibilities */ + return NULL; + } + } + + top = dfa_top(order); + if(top) + return top->name; + else + return NULL; +} + +const char *guess_ar(const char *buf, int buflen) +{ + int i; + const char *rv = NULL; + + /* encodings */ + guess_dfa cp1256 = DFA_INIT(guess_cp1256_st, guess_cp1256_ar, "CP1256"); + guess_dfa iso8859_6 = DFA_INIT(guess_iso8859_6_st, guess_iso8859_6_ar, "ISO-8859-6"); + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + + guess_dfa *top = NULL; + guess_dfa *order[] = { ORDER_AR, NULL }; + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + + /* special treatment of BOM */ + if (i == 0 && c == 0xff) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xfe) + return UCS_2LE; + } + } + if (i == 0 && c == 0xfe) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xff) + return UCS_2BE; + } + } + + rv = dfa_process(order, c); + if(rv) + return rv; + + if (dfa_none(order)) { + /* we ran out the possibilities */ + return NULL; + } + } + + top = dfa_top(order); + if (top) + return top->name; + else + return NULL; +} + +const char *guess_gr(const char *buf, int buflen) +{ + int i; + const char *rv = NULL; + + /* encodings */ + guess_dfa cp1253 = DFA_INIT(guess_cp1253_st, guess_cp1253_ar, "CP1253"); + guess_dfa iso8859_7 = DFA_INIT(guess_iso8859_7_st, guess_iso8859_7_ar, "ISO-8859-7"); + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + + guess_dfa *top = NULL; + guess_dfa *order[] = { ORDER_GR, NULL }; + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + + /* special treatment of BOM */ + if (i == 0 && c == 0xff) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xfe) + return UCS_2LE; + } + } + if (i == 0 && c == 0xfe) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xff) + return UCS_2BE; + } + } + + rv = dfa_process(order, c); + if(rv) + return rv; + + if (dfa_none(order)) { + /* we ran out the possibilities */ + return NULL; + } + } + + top = dfa_top(order); + if (top) + return top->name; + else + return NULL; +} + +const char *guess_ru(const char *buf, int buflen) +{ + int i; + const char *rv = NULL; + + /* encodings */ + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + guess_dfa cp1251 = DFA_INIT(guess_cp1251_st, guess_cp1251_ar, "CP1251"); + guess_dfa cp866 = DFA_INIT(guess_cp866_st, guess_cp866_ar, "CP866"); + guess_dfa koi8_u = DFA_INIT(guess_koi8_u_st, guess_koi8_u_ar, "KOI8-U"); + guess_dfa koi8_r = DFA_INIT(guess_koi8_r_st, guess_koi8_r_ar, "KOI8-R"); + guess_dfa iso8859_2 = DFA_INIT(guess_iso8859_2_st, guess_iso8859_2_ar, "ISO-8859-2"); + guess_dfa iso8859_5 = DFA_INIT(guess_iso8859_5_st, guess_iso8859_5_ar, "ISO-8859-5"); + + guess_dfa *top = NULL; + guess_dfa *order[] = { ORDER_RU, NULL }; + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + + /* special treatment of BOM */ + if (i == 0 && c == 0xff) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xfe) + return UCS_2LE; + } + } + if (i == 0 && c == 0xfe) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xff) + return UCS_2BE; + } + } + + rv = dfa_process(order, c); + if(rv) + return rv; + + if (dfa_none(order)) { + /* we ran out the possibilities */ + return NULL; + } + } + + top = dfa_top(order); + if (top) + return top->name; + else + return NULL; +} + +const char *guess_hw(const char *buf, int buflen) +{ + int i; + const char *rv = NULL; + + /* encodings */ + guess_dfa cp1255 = DFA_INIT(guess_cp1255_st, guess_cp1255_ar, "CP1255"); + guess_dfa iso8859_8 = DFA_INIT(guess_iso8859_8_st, guess_iso8859_8_ar, "ISO-8859-8-I"); + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + + guess_dfa *top = NULL; + guess_dfa *order[] = { ORDER_HW, NULL }; + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + + /* special treatment of BOM */ + if (i == 0 && c == 0xff) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xfe) + return UCS_2LE; + } + } + if (i == 0 && c == 0xfe) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xff) + return UCS_2BE; + } + } + + rv = dfa_process(order, c); + if(rv) + return rv; + + if (dfa_none(order)) { + /* we ran out the possibilities */ + return NULL; + } + } + + top = dfa_top(order); + if (top) + return top->name; + else + return NULL; +} + +const char *guess_pl(const char *buf, int buflen) +{ + int i; + const char *rv = NULL; + + /* encodings */ + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + guess_dfa cp1250 = DFA_INIT(guess_cp1250_st, guess_cp1250_ar, "CP1250"); + guess_dfa iso8859_2 = DFA_INIT(guess_iso8859_2_st, guess_iso8859_2_ar, "ISO-8859-2"); + + guess_dfa *top = NULL; + guess_dfa *order[] = { ORDER_PL, NULL }; + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + + /* special treatment of BOM */ + if (i == 0 && c == 0xff) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xfe) + return UCS_2LE; + } + } + if (i == 0 && c == 0xfe) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xff) + return UCS_2BE; + } + } + + rv = dfa_process(order, c); + if(rv) + return rv; + + if (dfa_none(order)) { + /* we ran out the possibilities */ + return NULL; + } + } + + top = dfa_top(order); + if (top) + return top->name; + else + return NULL; +} + +const char *guess_tr(const char *buf, int buflen) +{ + int i; + const char *rv = NULL; + + /* encodings */ + guess_dfa cp1254 = DFA_INIT(guess_cp1254_st, guess_cp1254_ar, "CP1254"); + guess_dfa iso8859_9 = DFA_INIT(guess_iso8859_9_st, guess_iso8859_9_ar, "ISO-8859-9"); + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + + guess_dfa *top = NULL; + guess_dfa *order[] = { ORDER_TR, NULL }; + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + + /* special treatment of BOM */ + if (i == 0 && c == 0xff) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xfe) + return UCS_2LE; + } + } + if (i == 0 && c == 0xfe) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xff) + return UCS_2BE; + } + } + + rv = dfa_process(order, c); + if(rv) + return rv; + + if (dfa_none(order)) { + /* we ran out the possibilities */ + return NULL; + } + } + + top = dfa_top(order); + if (top) + return top->name; + else + return NULL; +} + +const char *guess_bl(const char *buf, int buflen) +{ + int i; + const char *rv = NULL; + + /* encodings */ + guess_dfa cp1257 = DFA_INIT(guess_cp1257_st, guess_cp1257_ar, "CP1257"); + guess_dfa iso8859_13 = DFA_INIT(guess_iso8859_13_st, guess_iso8859_13_ar, "ISO-8859-13"); + guess_dfa utf8 = DFA_INIT(guess_utf8_st, guess_utf8_ar, "UTF-8"); + + guess_dfa *top = NULL; + guess_dfa *order[] = { ORDER_BL, NULL }; + + for (i = 0; i < buflen; i++) { + int c = (unsigned char) buf[i]; + + /* special treatment of BOM */ + if (i == 0 && c == 0xff) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xfe) + return UCS_2LE; + } + } + if (i == 0 && c == 0xfe) { + if (i < buflen - 1) { + c = (unsigned char) buf[i + 1]; + if (c == 0xff) + return UCS_2BE; + } + } + + rv = dfa_process(order, c); + if(rv) + return rv; + + if (dfa_none(order)) { + /* we ran out the possibilities */ + return NULL; + } + } + + top = dfa_top(order); + if (top) + return top->name; + else + return NULL; +} diff --git a/src/libguess/guess_tab.c b/src/libguess/guess_tab.c new file mode 100644 index 0000000..776d23e --- /dev/null +++ b/src/libguess/guess_tab.c @@ -0,0 +1,1419 @@ +/* State transition table for character code guessing */ +/* This file is automatically generated by guess.scm */ + +#include "dfa.h" + +static signed char guess_eucj_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, + }, + { /* state jis0201_kana */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, + { /* state jis0213_1 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -1, + }, + { /* state jis0213_2 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -1, + }, +}; + +static guess_arc guess_eucj_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 1, 0.8 }, /* init -> jis0201_kana */ + { 3, 0.95 }, /* init -> jis0213_2 */ + { 2, 1.0 }, /* init -> jis0213_1 */ + { 0, 1.0 }, /* jis0201_kana -> init */ + { 0, 1.0 }, /* jis0213_1 -> init */ + { 0, 1.0 }, /* jis0213_2 -> init */ +}; + +static signed char guess_sjis_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + -1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, + }, + { /* state jis0213 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -1, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -1, -1, -1, + }, +}; + +static guess_arc guess_sjis_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 1, 1.0 }, /* init -> jis0213 */ + { 0, 0.8 }, /* init -> init */ + { 1, 0.95 }, /* init -> jis0213 */ + { 0, 0.8 }, /* init -> init */ + { 0, 1.0 }, /* jis0213 -> init */ +}; + +static signed char guess_utf8_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 5, + 6, 7, 7, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, + { /* state 1byte_more */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, + { /* state 2byte_more1 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, + { /* state 2byte_more2 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, + { /* state 2byte_more3 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, + { /* state 3byte_more1 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, + { /* state 3byte_more2 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, + { /* state 3byte_more3 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, +}; + +static guess_arc guess_utf8_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 1, 1.0 }, /* init -> 1byte_more */ + { 2, 1.0 }, /* init -> 2byte_more1 */ + { 3, 1.0 }, /* init -> 2byte_more2 */ + { 4, 1.0 }, /* init -> 2byte_more3 */ + { 3, 1.0 }, /* init -> 2byte_more2 */ + { 5, 1.0 }, /* init -> 3byte_more1 */ + { 6, 1.0 }, /* init -> 3byte_more2 */ + { 7, 1.0 }, /* init -> 3byte_more3 */ + { 0, 1.0 }, /* 1byte_more -> init */ + { 1, 1.0 }, /* 2byte_more1 -> 1byte_more */ + { 1, 1.0 }, /* 2byte_more2 -> 1byte_more */ + { 1, 1.0 }, /* 2byte_more3 -> 1byte_more */ + { 3, 1.0 }, /* 3byte_more1 -> 2byte_more2 */ + { 3, 1.0 }, /* 3byte_more2 -> 2byte_more2 */ + { 3, 1.0 }, /* 3byte_more3 -> 2byte_more2 */ +}; + +static signed char guess_ucs2le_st[][256] = { + { /* state init */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, + }, + { /* state bom-le */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + }, + { /* state bom-be */ + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -1, + }, + { /* state byte2 */ + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + }, +}; + +static guess_arc guess_ucs2le_ar[] = { + { 2, 1.0 }, /* init -> bom-be */ + { 1, 1.0 }, /* init -> bom-le */ + { 3, 1.0 }, /* init -> byte2 */ + { 0, 1.0 }, /* bom-le -> init */ + { 0, 1.0 }, /* bom-be -> init */ + { 0, 1.0 }, /* byte2 -> init */ +}; + +static signed char guess_ucs2be_st[][256] = { + { /* state init */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, + }, + { /* state bom-le */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, 4, + }, + { /* state bom-be */ + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + }, + { /* state byte2 */ + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + }, +}; + +static guess_arc guess_ucs2be_ar[] = { + { 2, 1.0 }, /* init -> bom-be */ + { 1, 1.0 }, /* init -> bom-le */ + { 3, 1.0 }, /* init -> byte2 */ + { 0, 1.0 }, /* bom-le -> init */ + { 0, 1.0 }, /* bom-le -> init */ + { 0, 1.0 }, /* bom-be -> init */ + { 0, 1.0 }, /* byte2 -> init */ +}; + +static signed char guess_utf16_st[][256] = { + { /* state init */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, + }, + { /* state init1 */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + }, + { /* state bom-be */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, + }, + { /* state bom-le */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, + }, + { /* state byte2 */ + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + }, +}; + +static guess_arc guess_utf16_ar[] = { + { 2, 1.0 }, /* init -> bom-be */ + { 3, 1.0 }, /* init -> bom-le */ + { 4, 1.0 }, /* init1 -> byte2 */ + { 1, 1.0 }, /* bom-be -> init1 */ + { 1, 1.0 }, /* bom-le -> init1 */ + { 1, 1.0 }, /* byte2 -> init1 */ +}; + +static signed char guess_big5_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, + }, + { /* state 2byte */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, + }, +}; + +static guess_arc guess_big5_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 1, 1.0 }, /* init -> 2byte */ + { 0, 1.0 }, /* 2byte -> init */ +}; + +static signed char guess_gb2312_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, + }, + { /* state 2byte */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, + }, +}; + +static guess_arc guess_gb2312_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 1, 1.0 }, /* init -> 2byte */ + { 0, 1.0 }, /* 2byte -> init */ +}; + +static signed char guess_gb18030_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, + }, + { /* state 2byte */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, + }, + { /* state 4byte2 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, + { /* state 4byte3 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -1, + }, + { /* state 4byte4 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, +}; + +static guess_arc guess_gb18030_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 1, 1.0 }, /* init -> 2byte */ + { 2, 1.0 }, /* init -> 4byte2 */ + { 0, 1.0 }, /* 2byte -> init */ + { 3, 1.0 }, /* 4byte2 -> 4byte3 */ + { 4, 1.0 }, /* 4byte3 -> 4byte4 */ + { 0, 1.0 }, /* 4byte4 -> init */ +}; + +static signed char guess_euck_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, + }, + { /* state ks1001 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, + }, +}; + +static guess_arc guess_euck_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 1, 1.0 }, /* init -> ks1001 */ + { 0, 1.0 }, /* ks1001 -> init */ +}; + +static signed char guess_johab_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, 2, -1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, + }, + { /* state jamo51 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, + -1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, + }, + { /* state jamo42 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -1, + }, +}; + +static guess_arc guess_johab_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 1, 1.0 }, /* init -> jamo51 */ + { 2, 0.95 }, /* init -> jamo42 */ + { 0, 1.0 }, /* jamo51 -> init */ + { 0, 1.0 }, /* jamo42 -> init */ +}; + +static signed char guess_iso8859_6_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, 3, 4, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1, -1, -1, 6, + -1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -1, -1, -1, -1, -1, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, +}; + +static guess_arc guess_iso8859_6_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_cp1256_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + }, +}; + +static guess_arc guess_cp1256_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_iso8859_7_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, -1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, + }, +}; + +static guess_arc guess_iso8859_7_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_cp1253_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, -1, 2, 2, 2, 2, 2, 2, -1, 3, -1, 4, -1, -1, -1, -1, + -1, 5, 5, 5, 5, 5, 5, 5, -1, 6, -1, 7, -1, -1, -1, -1, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -1, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, -1, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -1, + }, +}; + +static guess_arc guess_cp1253_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_iso8859_8_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, -1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, -1, 4, 4, -1, + }, +}; + +static guess_arc guess_iso8859_8_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_cp1255_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, -1, 2, 2, 2, 2, 2, 2, 2, 2, -1, 3, -1, -1, -1, -1, + -1, 4, 4, 4, 4, 4, 4, 4, 4, 4, -1, 5, -1, -1, -1, -1, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -1, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -1, -1, 9, 9, -1, + }, +}; + +static guess_arc guess_cp1255_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_iso8859_9_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + }, +}; + +static guess_arc guess_iso8859_9_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_cp1254_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, -1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, + -1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -1, -1, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + }, +}; + +static guess_arc guess_cp1254_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_iso8859_5_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + }, +}; + +static guess_arc guess_iso8859_5_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_koi8_r_st[][256] = { + { /* state init */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + }, +}; + +static guess_arc guess_koi8_r_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_koi8_u_st[][256] = { + { /* state init */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1, 1, -1, 2, 2, -1, -1, -1, -1, -1, 3, -1, -1, + -1, -1, -1, 4, 4, -1, 5, 5, -1, -1, -1, -1, -1, 6, -1, -1, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + }, +}; + +static guess_arc guess_koi8_u_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_cp866_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, + }, +}; + +static guess_arc guess_cp866_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_cp1251_st[][256] = { + { /* state init */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, -1, 2, -1, -1, -1, -1, -1, -1, 3, -1, 4, 4, 4, 4, + 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, -1, 6, 6, 6, 6, + 6, 6, 6, 6, -1, 7, -1, -1, 8, -1, 9, -1, -1, -1, -1, 10, + -1, -1, 11, 11, 11, -1, -1, -1, 12, -1, 13, -1, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + }, +}; + +static guess_arc guess_cp1251_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_iso8859_2_st[][256] = { + { /* state init */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1, -1, 2, -1, 3, 3, -1, -1, 4, 4, 4, 4, -1, 5, 5, + -1, 6, -1, 7, -1, 8, 8, -1, -1, 9, 9, 9, 9, -1, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, -1, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, -1, 13, 13, 13, 13, 13, 13, 13, -1, + }, +}; + +static guess_arc guess_iso8859_2_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_cp1250_st[][256] = { + { /* state init */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, 3, 3, 3, 3, + 3, 3, -1, 4, -1, 5, -1, -1, -1, -1, 6, -1, -1, -1, -1, 7, + -1, -1, -1, 8, -1, -1, -1, -1, -1, 9, 9, -1, 10, -1, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, -1, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, -1, 14, 14, 14, 14, 14, 14, 14, -1, + }, +}; + +static guess_arc guess_cp1250_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_iso8859_13_st[][256] = { + { /* state init */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 2, -1, -1, -1, -1, 3, + -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, 5, -1, -1, -1, -1, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, -1, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, -1, 9, 9, 9, 9, 9, 9, 9, -1, + }, +}; + +static guess_arc guess_iso8859_13_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + +static signed char guess_cp1257_st[][256] = { + { /* state init */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, + 1, -1, 2, -1, 3, 3, 3, 3, -1, 4, -1, 5, -1, 6, 6, 6, + -1, 7, 7, 7, 7, 7, 7, 7, -1, 8, -1, 9, -1, 10, 10, -1, + 11, -1, 12, 12, 12, -1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + }, +}; + +static guess_arc guess_cp1257_ar[] = { + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ + { 0, 1.0 }, /* init -> init */ +}; + diff --git a/src/libguess/libguess.h b/src/libguess/libguess.h new file mode 100644 index 0000000..a7bae25 --- /dev/null +++ b/src/libguess/libguess.h @@ -0,0 +1,89 @@ +/* + * This code is derivative of guess.c of Gauche-0.8.3. + * The following is the original copyright notice. + */ + +/* + * Copyright (c) 2000-2003 Shiro Kawai, All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the authors nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _LIBGUESS_H +#define _LIBGUESS_H 1 + +#include <stdlib.h> +#include <string.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* prototypes */ +#ifdef LIBGUESS_CORE + +const char *guess_jp(const char *buf, int buflen); +const char *guess_tw(const char *buf, int buflen); +const char *guess_cn(const char *buf, int buflen); +const char *guess_kr(const char *buf, int buflen); +const char *guess_ru(const char *buf, int buflen); +const char *guess_ar(const char *buf, int buflen); +const char *guess_tr(const char *buf, int buflen); +const char *guess_gr(const char *buf, int buflen); +const char *guess_hw(const char *buf, int buflen); +const char *guess_pl(const char *buf, int buflen); +const char *guess_bl(const char *buf, int buflen); + +typedef const char *(*guess_impl_f)(const char *buf, int len); + +#endif + +int libguess_validate_utf8(const char *buf, int buflen); + +#define GUESS_REGION_JP "japanese" +#define GUESS_REGION_TW "taiwanese" +#define GUESS_REGION_CN "chinese" +#define GUESS_REGION_KR "korean" +#define GUESS_REGION_RU "russian" +#define GUESS_REGION_AR "arabic" +#define GUESS_REGION_TR "turkish" +#define GUESS_REGION_GR "greek" +#define GUESS_REGION_HW "hebrew" +#define GUESS_REGION_PL "polish" +#define GUESS_REGION_BL "baltic" + +typedef void (*libguess_result_f)(const char *encodingname, const char *res); + +const char *libguess_determine_encoding(const char *buf, int buflen, const char *langset); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libguess/meson.build b/src/libguess/meson.build new file mode 100644 index 0000000..629341f --- /dev/null +++ b/src/libguess/meson.build @@ -0,0 +1,15 @@ +libguess_sources = [ + 'dfa.c', + 'guess.c', + 'guess_impl.c' +] + + +libguess_lib = static_library('guess', + libguess_sources, + c_args: ['-DLIBGUESS_CORE'], + pic: true +) + + +libguess_inc = include_directories('.') diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..d6f738d --- /dev/null +++ b/src/meson.build @@ -0,0 +1,36 @@ +src_inc = include_directories('.') + + +config_h = configure_file(input: 'config.h.meson', + output: 'config.h', + configuration: conf) + + +config_h_full_path = join_paths(meson.current_build_dir(), 'config.h') + + +if cc.get_id() == 'gcc' or cc.get_id() == 'clang' + add_project_arguments('-include', config_h_full_path, language: 'c') + add_project_arguments('-include', config_h_full_path, language: 'cpp') +else + error('Please implement -include handling for your chosen compiler.') +endif + + +subdir('libguess') +subdir('libaudcore') +subdir('libaudtag') + + +if get_option('qt') + subdir('libaudqt') +endif + + +if get_option('dbus') + subdir('dbus') + subdir('audtool') +endif + + +subdir('audacious') diff --git a/win32/audacious.nsi.in b/win32/audacious.nsi.in new file mode 100644 index 0000000..3a6dce7 --- /dev/null +++ b/win32/audacious.nsi.in @@ -0,0 +1,129 @@ +; audacious.nsi +; Copyright 2013-2016 Carlo Bramini and John Lindgren +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; +; 1. Redistributions of source code must retain the above copyright notice, +; this list of conditions, and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright notice, +; this list of conditions, and the following disclaimer in the documentation +; provided with the distribution. +; +; This software is provided "as is" and without any warranty, express or +; implied. In no event shall the authors be liable for any damages arising from +; the use of this software. + +; Imports +!include "MUI2.nsh" + +; Version +!define VERSION "@PACKAGE_VERSION@" + +; Program name +Name "Audacious ${VERSION}" + +; Installer file name +OutFile "audacious-${VERSION}-win32.exe" + +; Location of local build +!define BUILDDIR "C:\aud-win32" + +; Installer icon +!define MUI_ICON "..\images\audacious.ico" +!define MUI_UNICON "..\images\audacious.ico" + +; Installer options +RequestExecutionLevel admin +SetCompressor /SOLID lzma + +; Default installation directory +InstallDir "$PROGRAMFILES\Audacious" + +; Registry uninstall key +!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\Audacious" + +; Path to uninstaller +!define UNINSTALLER "$INSTDIR\uninstall.exe" + +; Installer pages +!insertmacro MUI_PAGE_LICENSE "${BUILDDIR}\README.txt" +!insertmacro MUI_PAGE_COMPONENTS +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES + +; Uninstaller pages +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +; Languages +!insertmacro MUI_LANGUAGE "English" + +Section "Audacious" InstallSection + SectionIn RO + + SetOutPath "$INSTDIR" + File "${BUILDDIR}\README.txt" + + RMDir /r "$INSTDIR\bin" + SetOutPath "$INSTDIR\bin" + File /r "${BUILDDIR}\bin\*.*" + + RMDir /r "$INSTDIR\etc" + SetOutPath "$INSTDIR\etc" + File /r "${BUILDDIR}\etc\*.*" + + RMDir /r "$INSTDIR\lib" + SetOutPath "$INSTDIR\lib" + File /r "${BUILDDIR}\lib\*.*" + + RMDir /r "$INSTDIR\share" + SetOutPath "$INSTDIR\share" + File /r "${BUILDDIR}\share\*.*" + + ; create uninstaller + WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "Audacious" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${VERSION}" + WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "Audacious developers" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "${UNINSTALLER}" + WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "${UNINSTALLER}" + WriteRegDWORD HKLM "${UNINST_KEY}" "NoModify" 1 + WriteRegDWORD HKLM "${UNINST_KEY}" "NoRepair" 1 + + ; estimate installed size + SectionGetSize InstallSection $0 + WriteRegDWORD HKLM "${UNINST_KEY}" "EstimatedSize" $0 + + WriteUninstaller ${UNINSTALLER} + +SectionEnd + +; Optional sections +Section "Add to Start Menu" StartMenuSection + + SetShellVarContext all + SetOutPath "$INSTDIR\bin" ; sets the shortcut's working directory + CreateShortCut "$SMPROGRAMS\Audacious.lnk" "$INSTDIR\bin\audacious.exe" + +SectionEnd + +Section "Add to Desktop" DesktopSection + + SetShellVarContext all + SetOutPath "$INSTDIR\bin" ; sets the shortcut's working directory + CreateShortCut "$DESKTOP\Audacious.lnk" "$INSTDIR\bin\audacious.exe" + +SectionEnd + +Section "Uninstall" UninstallSection + + RMDir /r "$INSTDIR" + + SetShellVarContext all + Delete "$SMPROGRAMS\Audacious.lnk" + Delete "$DESKTOP\Audacious.lnk" + + DeleteRegKey HKLM "${UNINST_KEY}" + +SectionEnd diff --git a/win32/merge.sh b/win32/merge.sh new file mode 100644 index 0000000..797d5e9 --- /dev/null +++ b/win32/merge.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +# Quick-and-dirty script for updating a Windows release folder + +rm -rf /C/aud-win32/share/locale + +cd /C/aud-win32 +for i in `find -type f` ; do + if test -f /C/audacious/win32/override/$i ; then + cp /C/audacious/win32/override/$i $i + elif test -f /C/msys32/mingw32/$i ; then + cp /C/msys32/mingw32/$i $i + elif test -f /C/Qt/5.12.5/mingw73_32/$i ; then + cp /C/Qt/5.12.5/mingw73_32/$i $i + elif test -f /C/GTK/$i ; then + cp /C/GTK/$i $i + elif test -f /C/libs/$i ; then + cp /C/libs/$i $i + elif test -f /C/aud/$i ; then + cp /C/aud/$i $i + else + echo Not found: $i + fi +done + +for i in `find -name *.dll` ; do strip -s $i ; done +for i in `find -name *.exe` ; do strip -s $i ; done + +cd /C/GTK +for i in `find ./share/locale -name gtk20.mo` ; do + mkdir -p /C/aud-win32/${i%%/gtk20.mo} + cp $i /C/aud-win32/$i +done + +cd /C/aud +for i in `find ./share/locale -name audacious.mo` ; do + mkdir -p /C/aud-win32/${i%%/audacious.mo} + cp $i /C/aud-win32/$i +done +for i in `find ./share/locale -name audacious-plugins.mo` ; do + mkdir -p /C/aud-win32/${i%%/audacious-plugins.mo} + cp $i /C/aud-win32/$i +done diff --git a/win32/notes.html b/win32/notes.html new file mode 100755 index 0000000..ed25426 --- /dev/null +++ b/win32/notes.html @@ -0,0 +1,602 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> + +<html> +<head> +<meta http-equiv="Content-type" content="text/html;charset=UTF-8"> +<title>Notes for Building Audacious on Windows + + + +

Notes for Building Audacious on Windows

+ +

John Lindgren
+April 13, 2017

+ +

Several patch files should accompany this document.

+ +

Set up MSYS2 environment

+ +

Download and run:
+ +http://repo.msys2.org/distrib/i686/msys2-i686-20161025.exe

+ +

Accept the default options to install to C:\msys32.

+ +

Edit C:\msys32\home\<user>\.bashrc and add the following lines:

+

export PATH="$PATH:/C/cmake/bin:/C/GTK/bin:/C/libs/bin:/C/aud/bin"
+export PKG_CONFIG_PATH=/C/Qt/5.12.5/mingw73_32/lib/pkgconfig:/C/GTK/lib/pkgconfig:/C/libs/lib/pkgconfig:/C/aud/lib/pkgconfig
+export C_INCLUDE_PATH=/C/GTK/include:/C/libs/include
+export CPLUS_INCLUDE_PATH=/C/GTK/include:/C/libs/include
+export LIBRARY_PATH=/C/GTK/lib:/C/libs/lib

+ +

In the MinGW shell (MSYS2 MinGW 32-bit, not MSYS2 MSYS):

+ +

pacman -Syu
+pacman -S autoconf automake bison gperf libtool mingw-w64-i686-gcc mingw-w64-i686-gettext make perl-XML-Parser pkg-config python2

+ +

Install CMake

+ +

Download and run:
+ +https://cmake.org/files/v3.8/cmake-3.8.2-win32-x86.msi

+ +

Install to C:\cmake.

+ +

Install Qt (for Qt builds)

+ +

Download and run (choose another mirror if desired):
+ +http://qt.mirror.constant.com/archive/online_installers/3.1/qt-unified-windows-x86-3.1.1-online.exe

+ +

Choose the following install options:
+

  • Skip the Qt account login page
  • +
  • Use the default installation path (C:\Qt)
  • +
  • Install Qt 5.12.5 for MinGW 7.3.0 32-bit

+ +

Install libpng

+ +

Download and unzip to C:\libpng:
+ +https://sourceforge.net/projects/libpng/files/libpng16/1.6.29/libpng-1.6.29.tar.xz/download

+ +

In the MinGW shell:

+

cd /C/libpng
+./configure --prefix=/C/GTK
+make
+make install

+ +

Install libjpeg-turbo

+ +

Download and unzip to C:\libjpeg:
+ +https://sourceforge.net/projects/libjpeg-turbo/files/1.5.1/libjpeg-turbo-1.5.1.tar.gz/download

+ +

In the MinGW shell:

+

cd /C/libjpeg
+./configure --prefix=/C/GTK --without-simd --without-turbojpeg
+make
+make install

+ +

Install libffi

+ +

Download and unzip to C:\libffi:
+ +ftp://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz

+ +

In the MinGW shell:

+

cd /C/libffi
+./configure --prefix=/C/GTK --with-gcc-arch=i686
+make
+make install

+ +

Install GLib

+ +

Download and unzip to C:\glib:
+ +http://ftp.gnome.org/pub/GNOME/sources/glib/2.52/glib-2.52.3.tar.xz

+ +

Apply the recursive patches glib-2-52.diff and glib-gettext-fix.diff.

+ +

In the MinGW shell:

+

cd /C/glib
+CFLAGS="-O2 -march=i686" ./configure --prefix=/C/GTK --with-pcre=internal
+make
+make install

+ +

Install pixman

+ +

Download and unzip to C:\pixman:
+ +https://www.cairographics.org/releases/pixman-0.34.0.tar.gz

+ +

In the MinGW shell:

+

cd /C/pixman
+./configure --prefix=/C/GTK --disable-sse2 --disable-ssse3
+make
+make install

+ +

Install Cairo

+ +

Download and unzip to C:\cairo:
+ +https://www.cairographics.org/releases/cairo-1.14.8.tar.xz

+ +

In the MinGW shell:

+

cd /C/cairo
+./configure --prefix=/C/GTK --disable-interpreter
+make
+make install

+ +

Install FreeType

+ +

Download and unzip to C:\freetype:
+ +https://sourceforge.net/projects/freetype/files/freetype2/2.9/freetype-2.9.tar.bz2/download

+ +

In the MinGW shell:

+

cd /C/freetype
+./configure --prefix=/C/GTK
+make
+make install

+ +

Install HarfBuzz

+ +

Download and unzip to C:\harfbuzz:
+ +https://www.freedesktop.org/software/harfbuzz/release/harfbuzz-1.7.4.tar.bz2

+ +

In the MinGW shell:

+

cd /C/harfbuzz
+./configure --prefix=/C/GTK
+make
+make install

+ +

Install Fontconfig

+ +

Download and unzip to C:\fontconfig:
+ +https://www.freedesktop.org/software/fontconfig/release/fontconfig-2.12.6.tar.bz2

+ +

In the MinGW shell:

+

cd /C/fontconfig
+./configure --prefix=/C/GTK
+make
+make install

+ +

Install Pango

+ +

Download and unzip to C:\pango:
+ +http://ftp.gnome.org/pub/GNOME/sources/pango/1.40/pango-1.40.5.tar.xz

+ +

In the MinGW shell:

+

cd /C/pango
+./configure --prefix=/C/GTK
+make
+make install

+ +

Install gdk-pixbuf

+ +

Download and unzip to C:\gdk-pixbuf:
+ +http://ftp.gnome.org/pub/GNOME/sources/gdk-pixbuf/2.36/gdk-pixbuf-2.36.6.tar.xz

+ +

Apply the patch gdk-pixbuf-util.c.diff to C:\gdk-pixbuf\gdk-pixbuf\gdk-pixbuf-util.c.

+ +

In the MinGW shell:

+

cd /C/gdk-pixbuf
+./configure --prefix=/C/GTK --enable-relocations --without-gdiplus --without-libtiff --with-included-loaders=bmp,jpeg,png
+make
+make install

+ +

Install libcroco

+ +

Download and unzip to C:\libcroco:
+ +http://ftp.gnome.org/pub/GNOME/sources/libcroco/0.6/libcroco-0.6.12.tar.xz

+ +

In the MinGW shell:

+

cd /C/libcroco
+./configure --prefix=/C/GTK
+make
+make install

+ +

Install librsvg

+ +

Download and unzip to C:\librsvg:
+ +http://ftp.gnome.org/pub/GNOME/sources/librsvg/2.40/librsvg-2.40.20.tar.xz

+ +

In the MinGW shell:

+

cd /C/librsvg
+./configure --prefix=/C/GTK --disable-introspection
+make
+make install

+ +

Install ATK

+ +

Download and unzip to C:\atk:
+ +http://ftp.gnome.org/pub/gnome/sources/atk/2.24/atk-2.24.0.tar.xz

+ +

Apply the patch atkprivate.c.diff to C:\atk\atk\atkprivate.c.

+ +

In the MinGW shell:

+

cd /C/atk
+./configure --prefix=/C/GTK
+make
+make install

+ +

Install GTK+

+ +

Download and unzip to C:\gtksrc:
+ +http://ftp.gnome.org/pub/GNOME/sources/gtk+/2.24/gtk+-2.24.31.tar.xz

+ +

Apply the patch gdkwindow-win32.c.diff to C:\gtksrc\gdk\win32\gdkwindow-win32.c.
+Apply the patch gtkicontheme.c.diff to C:\gtksrc\gtk\gtkicontheme.c.
+Apply the patch gtkmain.c.diff to C:\gtksrc\gtk\gtkmain.c.
+Apply the recursive patch gtk-parentheses.diff.

+ +

In the MinGW shell:

+

cd /C/gtksrc
+./configure --prefix=/C/GTK
+make
+make install

+ +

It may be necessary to run the MinGW shell with administrative privileges +for GTK+ to build successfully.

+ +

Install intltool

+ +

Download and unzip to C:\intltool:
+ +http://ftp.gnome.org/pub/GNOME/sources/intltool/0.40/intltool-0.40.6.tar.bz2

+ +

In the MinGW shell:

+

cd /C/intltool
+./configure --prefix=/C/GTK
+make
+make install

+ +

Install GNOME Icon Theme

+ +

Download and unzip to C:\gnome-icon-theme:
+ +http://ftp.gnome.org/pub/GNOME/sources/gnome-icon-theme/3.12/gnome-icon-theme-3.12.0.tar.xz

+ +

In the MinGW shell:

+

cd /C/gnome-icon-theme
+./configure --prefix=/C/GTK --disable-icon-mapping
+make
+make install

+ +

It may be necessary to run the MinGW shell with administrative privileges +for GNOME Icon Theme to install successfully.

+ +

Install GNU regex

+ +

Download and unzip to C:\libs:
+ +http://sourceforge.net/projects/mingw/files/Other/UserContributed/regex/mingw-regex-2.5.1/mingw-libgnurx-2.5.1-bin.tar.gz/download
+ +http://sourceforge.net/projects/mingw/files/Other/UserContributed/regex/mingw-regex-2.5.1/mingw-libgnurx-2.5.1-dev.tar.gz/download

+ +

Install libxml

+ +

Download and unzip to C:\libxml:
+ +ftp://xmlsoft.org/libxml2/libxml2-2.9.9.tar.gz

+ +

In the MinGW shell:

+

cd /C/libxml
+./configure --prefix=/C/libs --with-python=no
+make
+make install

+ +

Install mpg123

+ +

Download and unzip to C:\mpg123:
+ +http://mpg123.de/download/mpg123-1.25.13.tar.bz2

+ +

In the MinGW shell:

+

cd /C/mpg123
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libfaad

+ +

Download and unzip to C:\libfaad:
+ +https://sourceforge.net/projects/faac/files/faad2-src/faad2-2.8.0/faad2-2.8.8.tar.gz/download

+ +

Apply the patch libfaad-decoder.c.diff to C:\libfaad\decoder.c.

+ +

In the MinGW shell:

+

cd /C/libfaad
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libsndfile

+ +

Download and unzip to C:\libsndfile:
+ +http://www.mega-nerd.com/libsndfile/files/libsndfile-1.0.28.tar.gz

+ +

In the MinGW shell:

+

cd /C/libsndfile
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libbs2b

+ +

Download and unzip to C:\libbs2b:
+ +http://sourceforge.net/projects/bs2b/files/libbs2b/3.1.0/libbs2b-3.1.0.tar.bz2/download

+ +

In the MinGW shell:

+

cd /C/libbs2b
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libcdio

+ +

Download and unzip to C:\libcdio:
+ +http://ftp.gnu.org/gnu/libcdio/libcdio-2.1.0.tar.bz2

+ +

Download and unzip to C:\libcdio-paranoia:
+ +http://ftp.gnu.org/gnu/libcdio/libcdio-paranoia-10.2+2.0.0.tar.bz2

+ +

In the MinGW shell:

+

cd /C/libcdio
+./configure --prefix=/C/libs
+make
+make install
+cd /C/libcdio-paranoia
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libcddb

+ +

Download and unzip to C:\libcddb:
+ +http://sourceforge.net/projects/libcddb/files/libcddb/1.3.2/libcddb-1.3.2.tar.bz2/download

+ +

Apply the recursive patch libcddb-1.3.diff.

+ +

In the MinGW shell:

+

cd /C/libcddb
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libcue

+ +

Download and unzip to C:\libcue:
+ +https://github.com/lipnitsk/libcue/archive/v2.2.1.tar.gz

+ +

In the MinGW shell:

+

cd /C/libcue
+cmake -DCMAKE_INSTALL_PREFIX=/C/libs -DBUILD_SHARED_LIBS=1 -G"MSYS Makefiles"
+make
+make install

+ +

Install LAME

+ +

Download and unzip to C:\lame:
+ +https://sourceforge.net/projects/lame/files/lame/3.100/lame-3.100.tar.gz/download

+ +

Apply the patch libmp3lame.sym.diff to C:\lame\include\libmp3lame.sym.

+ +

In the MinGW shell:

+

cd /C/lame
+./configure --prefix=/C/libs --disable-frontend
+make
+make install

+ +

Install libflac

+ +

Download and unzip to C:\libflac:
+ +https://ftp.osuosl.org/pub/xiph/releases/flac/flac-1.3.3.tar.xz

+ +

In the MinGW shell:

+

cd /C/libflac
+./configure --prefix=/C/libs --disable-asm-optimizations --disable-sse --disable-ogg
+make
+make install

+ +

Install libogg

+ +

Download and unzip to C:\libogg:
+ +https://ftp.osuosl.org/pub/xiph/releases/ogg/libogg-1.3.4.tar.xz

+ +

In the MinGW shell:

+

cd /C/libogg
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libvorbis

+ +

Download and unzip to C:\libvorbis:
+ +https://ftp.osuosl.org/pub/xiph/releases/vorbis/libvorbis-1.3.6.tar.xz

+ +

In the MinGW shell:

+

cd /C/libvorbis
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libneon

+ +

Download and unzip to C:\libneon:
+ +http://www.webdav.org/neon/neon-0.30.2.tar.gz

+ +

Apply the recursive patch neon-0.30.diff.

+ +

In the MinGW shell:

+

cd /C/libneon
+./autogen.sh
+./configure --prefix=/C/libs --enable-shared
+make
+make install

+ +

Install libsamplerate

+ +

Download and unzip to C:\libsamplerate:
+ +http://www.mega-nerd.com/SRC/libsamplerate-0.1.9.tar.gz

+ +

Apply the recursive patch libsamplerate-0.1.diff.

+ +

In the MinGW shell:

+

cd /C/libsamplerate
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libwavpack

+ +

Download and unzip to C:\libwavpack:
+ +http://www.wavpack.com/wavpack-5.1.0.tar.bz2

+ +

Apply the recursive patch wavpack-4.80.diff.

+ +

In the MinGW shell:

+

cd /C/libwavpack
+./configure --prefix=/C/libs
+make
+make install

+ +

Install FFmpeg

+ +

Download and unzip to C:\ffmpeg:
+ +http://ffmpeg.org/releases/ffmpeg-4.2.1.tar.xz

+ +

In the MinGW shell:

+

cd /C/ffmpeg
+./configure --prefix=/C/libs --enable-shared --disable-yasm --cpu=i686
+make
+make install

+ +

Install libmms

+ +

Download and unzip to C:\libmms:
+ +http://sourceforge.net/projects/libmms/files/libmms/0.6.4/libmms-0.6.4.tar.gz/download

+ +

Apply the recursive patch libmms-strndup.diff.

+ +

In the MinGW shell:

+

cd /C/libmms
+cp /C/msys32/usr/share/libtool/build-aux/ltmain.sh .
+autoreconf
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libbinio

+ +

Download and unzip to C:\libbinio:
+ +https://github.com/adplug/libbinio/releases/download/libbinio-1.5/libbinio-1.5.tar.bz2

+ +

In the MinGW shell:

+

cd /C/libbinio
+./configure --prefix=/C/libs
+make
+make install

+ +

Install adplug

+ +

Download and unzip to C:\adplug:
+ +https://github.com/adplug/adplug/releases/download/adplug-2.3.1/adplug-2.3.1.tar.bz2

+ +

In the MinGW shell:

+

cd /C/adplug
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libmodplug

+ +

Download and unzip to C:\libmodplug:
+ +https://sourceforge.net/projects/modplug-xmms/files/libmodplug/0.8.9.0/libmodplug-0.8.9.0.tar.gz/download

+ +

In the MinGW shell:

+

cd /C/libmodplug
+./configure --prefix=/C/libs
+make
+make install

+ +

Install libsidplayfp

+ +

Download and unzip to C:\libsidplayfp:
+ +https://sourceforge.net/projects/sidplay-residfp/files/libsidplayfp/2.0/libsidplayfp-2.0.1.tar.gz/download

+ +

In the MinGW shell:

+

cd /C/libsidplayfp
+./configure --prefix=/C/libs
+make
+make install

+ +

Install FluidSynth

+ +

Download and unzip to C:\fluidsynth (ignore "cannot create symlink" errors):
+ +http://sourceforge.net/projects/fluidsynth/files/fluidsynth-1.1.6/fluidsynth-1.1.6.tar.bz2/download

+ +

Apply the recursive patch fluidsynth.diff.

+ +

In the MinGW shell:

+

cd /C/fluidsynth
+./autogen.sh
+./configure --prefix=/C/libs
+make
+make install

+ +

Install Audacious

+ +

Download and unzip to C:\audacious:
+ +https://distfiles.audacious-media-player.org/audacious-3.8.tar.bz2

+ +

In the MinGW shell:

+

cd /C/audacious
+./configure --prefix=/C/aud
+make
+make install

+ +

Install Audacious Plugins

+ +

Download and unzip to C:\audacious-plugins:
+ +https://distfiles.audacious-media-player.org/audacious-plugins-3.8.tar.bz2

+ +

In the MinGW shell:

+

cd /C/audacious-plugins
+./configure --prefix=/C/aud
+make
+make install

+ + + diff --git a/win32/override/README.txt.in b/win32/override/README.txt.in new file mode 100644 index 0000000..1e528d8 --- /dev/null +++ b/win32/override/README.txt.in @@ -0,0 +1,88 @@ +Audacious @PACKAGE_VERSION@ for Windows + + https://audacious-media-player.org + +Audacious is free and open source software. By installing Audacious, you agree +to be bound by various licenses governing its use and redistribution. + +Build ID: @BUILDSTAMP@ + +LICENSE + +@COPYRIGHT@ + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions, and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + provided with the distribution. + +This software is provided "as is" and without any warranty, express or +implied. In no event shall the authors be liable for any damages arising +from the use of this software. + +EXCEPTIONS + +Audacious includes icons adapted from the Paper Icon Set by Sam Hewitt. These +icons are distributed under the Creative Commons Attribution-ShareAlike 4.0 +license (see https://creativecommons.org/licenses/by-sa/4.0/). + +Please note that many of the plugins distributed with Audacious are under +different licenses, whose full text may be found either in the "About" window +of each plugin or in the source code. + +Audacious would not exist without the efforts of numerous other free and open +source software projects, which are listed below. By installing Audacious, you +also agree to all relevant licenses governing these projects. The source code +and license of each project can be found on the Internet. + + Project Website + ------- ------- + + MinGW http://mingw.org + GNU libc http://www.gnu.org/software/libc + GNU libstdc++ http://gcc.gnu.org/libstdc++ + GNU gettext http://www.gnu.org/software/gettext + GNU libiconv http://www.gnu.org/software/libiconv + zlib http://zlib.net + libpng http://libpng.org/pub/png + libjpeg-turbo http://libjpeg-turbo.org/ + libffi http://sourceware.org/libffi + GLib http://developer.gnome.org/glib + Pixman http://pixman.org + Cairo http://cairographics.org + Pango http://www.pango.org + GDK-Pixbuf http://developer.gnome.org/gdk-pixbuf + ATK http://developer.gnome.org/atk + GTK+ http://www.gtk.org + libguess http://atheme.org/projects/libguess.html + libxml2 http://xmlsoft.org + mpg123 http://mpg123.de + FAAD2 http://www.audiocoding.com/faad2.html + libsndfile http://mega-nerd.com/libsndfile + bs2b http://bs2b.sourceforge.net + GNU libcdio http://www.gnu.org/software/libcdio + libcddb http://libcddb.sourceforge.net + libcue http://github.com/lipnitsk/libcue + LAME http://lame.sourceforge.net + libflac http://xiph.org/flac + libogg http://xiph.org/ogg + libvorbis http://xiph.org/vorbis + neon http://webdav.org/neon + libsamplerate http://mega-nerd.com/SRC + WavPack http://wavpack.com + FFmpeg http://ffmpeg.org + ModPlug http://modplug-xmms.sourceforge.net + AdPlug http://adplug.github.io + libmms http://libmms.sourceforge.net + sidplayfp http://sidplay-residfp.sourceforge.net + FluidSynth http://fluidsynth.org + +If you are an author of one of these projects and do not wish your software +included with Audacious in binary form, please contact us via the support forum: + + https://redmine.audacious-media-player.org/projects/audacious/boards diff --git a/win32/override/etc/gtk-2.0/gtkrc b/win32/override/etc/gtk-2.0/gtkrc new file mode 100644 index 0000000..14456b5 --- /dev/null +++ b/win32/override/etc/gtk-2.0/gtkrc @@ -0,0 +1 @@ +gtk-icon-theme-name = "gnome" diff --git a/win32/override/share/icons/gnome/16x16/apps/audacious.png b/win32/override/share/icons/gnome/16x16/apps/audacious.png new file mode 100644 index 0000000..996566e Binary files /dev/null and b/win32/override/share/icons/gnome/16x16/apps/audacious.png differ diff --git a/win32/patches/atkprivate.c.diff b/win32/patches/atkprivate.c.diff new file mode 100644 index 0000000..b66c20d --- /dev/null +++ b/win32/patches/atkprivate.c.diff @@ -0,0 +1,17 @@ +--- atk/atkprivate.c.0 2017-01-09 09:37:24.000000000 -0500 ++++ atk/atkprivate.c 2018-05-30 23:18:27.572970500 -0400 +@@ -77,9 +77,13 @@ + g_free (root); + + /* atk_localedir is passed to bindtextdomain() which isn't +- * UTF-8-aware. ++ * UTF-8-aware. Try to convert the path back to the legacy ++ * 8-bit locale. If that's impossible, there's not much we ++ * can do so just return the original build-time path. + */ + atk_localedir = g_win32_locale_filename_from_utf8 (temp); ++ if (atk_localedir == NULL) ++ atk_localedir = g_strdup (ATK_LOCALEDIR); + g_free (temp); + } + return atk_localedir; diff --git a/win32/patches/fluidsynth.diff b/win32/patches/fluidsynth.diff new file mode 100644 index 0000000..898fe37 --- /dev/null +++ b/win32/patches/fluidsynth.diff @@ -0,0 +1,36 @@ +diff -ur fluidsynth-1.1.6.0/configure.ac fluidsynth-1.1.6/configure.ac +--- fluidsynth-1.1.6.0/configure.ac 2012-08-16 00:01:13 -0400 ++++ fluidsynth-1.1.6/configure.ac 2013-11-01 13:19:31 -0400 +@@ -68,7 +68,7 @@ + AC_DEFINE(DARWIN, 1, [Define if building for Mac OS X Darwin]) + ;; + mingw*) +- mingw32_support="yes" ++ mingw32_support="no" + CFLAGS="$CFLAGS -mms-bitfields" + AC_DEFINE(MINGW32, 1, [Define if using the MinGW32 environment]) + LIBFLUID_LIBS="-ldsound -lwinmm -lws2_32" +diff -ur fluidsynth-1.1.6.0/src/config_win32.h.in fluidsynth-1.1.6/src/config_win32.h.in +--- fluidsynth-1.1.6.0/src/config_win32.h.in 2012-08-16 00:01:13 -0400 ++++ fluidsynth-1.1.6/src/config_win32.h.in 2013-11-01 13:26:42 -0400 +@@ -10,8 +10,6 @@ + #define HAVE_IO_H 1 + #define HAVE_WINDOWS_H 1 + +-#define DSOUND_SUPPORT 1 +-#define WINMIDI_SUPPORT 1 + #define WITH_FLOAT 1 + + #define snprintf _snprintf +diff -ur fluidsynth-1.1.6.0/src/utils/fluidsynth_priv.h fluidsynth-1.1.6/src/utils/fluidsynth_priv.h +--- fluidsynth-1.1.6.0/src/utils/fluidsynth_priv.h 2012-08-16 00:01:13 -0400 ++++ fluidsynth-1.1.6/src/utils/fluidsynth_priv.h 2013-11-01 13:31:12 -0400 +@@ -125,8 +125,6 @@ + #define snprintf _snprintf + #define vsnprintf _vsnprintf + +-#define DSOUND_SUPPORT 1 +-#define WINMIDI_SUPPORT 1 + #define STDIN_FILENO 0 + #define STDOUT_FILENO 1 + #define STDERR_FILENO 2 diff --git a/win32/patches/gdk-pixbuf-util.c.diff b/win32/patches/gdk-pixbuf-util.c.diff new file mode 100644 index 0000000..6abea31 --- /dev/null +++ b/win32/patches/gdk-pixbuf-util.c.diff @@ -0,0 +1,18 @@ +--- gdk-pixbuf/gdk-pixbuf-util.c.0 2016-12-20 08:43:26.000000000 -0500 ++++ gdk-pixbuf/gdk-pixbuf-util.c 2018-05-30 22:57:54.900626100 -0400 +@@ -363,9 +363,13 @@ + { + gchar *retval; + /* The localedir is passed to bindtextdomain() which isn't +- * UTF-8-aware. +- */ ++ * UTF-8-aware. Try to convert the path back to the legacy ++ * 8-bit locale. If that's impossible, there's not much we ++ * can do so just return the original build-time path. ++ */ + retval = g_win32_locale_filename_from_utf8 (temp); ++ if (retval == NULL) ++ retval = g_strdup (GDK_PIXBUF_LOCALEDIR); + g_free (temp); + return retval; + } diff --git a/win32/patches/gdkwindow-win32.c.diff b/win32/patches/gdkwindow-win32.c.diff new file mode 100644 index 0000000..1919095 --- /dev/null +++ b/win32/patches/gdkwindow-win32.c.diff @@ -0,0 +1,15 @@ +--- gdkwindow-win32.c.0 2014-09-29 16:02:16 -0400 ++++ gdkwindow-win32.c 2015-12-24 06:08:41 -0500 +@@ -3202,6 +3202,12 @@ + SWP_FRAMECHANGED | SWP_NOACTIVATE | + SWP_NOREPOSITION | SWP_NOZORDER); + ++ /* For reasons not clearly understood, the first call to SetWindowPos will ++ * sometimes ignore/adjust the window size we requested. The second call ++ * below works around this bug/feature. */ ++ SetWindowPos (GDK_WINDOW_HWND (window), NULL, ++ 0, 0, rect.right - rect.left, rect.bottom - rect.top, ++ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER); + } + + static void diff --git a/win32/patches/glib-2-52.diff b/win32/patches/glib-2-52.diff new file mode 100644 index 0000000..624090f --- /dev/null +++ b/win32/patches/glib-2-52.diff @@ -0,0 +1,168 @@ +diff --git a/gio/gwin32appinfo.c b/gio/gwin32appinfo.c +index b547012b6..4eb7d96c1 100644 +--- a/gio/gwin32appinfo.c ++++ b/gio/gwin32appinfo.c +@@ -2777,7 +2777,7 @@ read_classes (GWin32RegistryKey *classes_root) + (class_name_len <= 1)) + continue; + +- if (class_name[0] == L'.') ++ if (class_name[0] == L'.' || wcscmp(class_name, L"Folder") == 0) + read_class_extension (classes_root, class_name, class_name_len); + else + { +@@ -3953,6 +3953,79 @@ Legend: (from http://msdn.microsoft.com/en-us/library/windows/desktop/cc144101%2 + return result; + } + ++/* This is somewhat similar to g_shell_parse_argv, but handles only unquoting. ++ * Escape sequences are not supported since '\' is a path delimiter on Windows. */ ++static void ++split_command_line (const gchar *command_line, ++ gint *argcp, ++ gchar ***argvp) ++{ ++ GSList *args = NULL; ++ gchar current_quote = '\0'; ++ const gchar *current_token = NULL; ++ const gchar *next = command_line; ++ GSList *arg_iter; ++ gchar **argv_iter; ++ ++ for (next = command_line;; next++) ++ { ++ if (current_token == NULL) ++ { ++ /* a token begins with: ++ * a quote ++ * a non-whitespace character ++ */ ++ if (*next != '\0' && !g_ascii_isspace(*next)) ++ { ++ if (*next == '\'' || *next == '"') ++ { ++ current_quote = *next; ++ current_token = next + 1; ++ } ++ else ++ { ++ current_token = next; ++ } ++ } ++ } ++ else /* current_token != NULL */ ++ { ++ /* a token ends with: ++ * a NUL ++ * a matching end quote ++ * an unquoted whitespace character ++ */ ++ if (*next == '\0' || ++ *next == current_quote || ++ (current_quote == '\0' && g_ascii_isspace (*next))) ++ { ++ args = g_slist_prepend (args, g_strndup (current_token, next - current_token)); ++ ++ current_quote = '\0'; ++ current_token = NULL; ++ } ++ } ++ ++ if (*next == '\0') ++ break; ++ } ++ ++ args = g_slist_reverse (args); ++ ++ /* build NULL-terminated argv array */ ++ *argcp = g_slist_length (args); ++ *argvp = g_new (gchar*, *argcp + 1); ++ ++ argv_iter = *argvp; ++ ++ for (arg_iter = args; arg_iter != NULL; arg_iter = arg_iter->next) ++ *argv_iter++ = arg_iter->data; ++ ++ *argv_iter = NULL; ++ ++ g_slist_free (args); ++} ++ + static gboolean + expand_application_parameters (GWin32AppInfo *info, + const gchar *exec_line, +@@ -3966,7 +4039,6 @@ expand_application_parameters (GWin32AppInfo *info, + const char *p = exec_line; + GString *expanded_exec; + gboolean res; +- gchar *a_char; + + if (exec_line == NULL) + { +@@ -4005,20 +4077,9 @@ expand_application_parameters (GWin32AppInfo *info, + expand_macro ('f', expanded_exec, info, stat_obj_list, objs); + } + +- /* Replace '\\' with '/', because g_shell_parse_argv considers them +- * to be escape sequences. +- */ +- for (a_char = expanded_exec->str; +- a_char <= &expanded_exec->str[expanded_exec->len]; +- a_char++) +- { +- if (*a_char == '\\') +- *a_char = '/'; +- } +- +- res = g_shell_parse_argv (expanded_exec->str, argc, argv, error); ++ split_command_line (expanded_exec->str, argc, argv); + g_string_free (expanded_exec, TRUE); +- return res; ++ return TRUE; + } + + +@@ -4286,7 +4347,7 @@ g_win32_app_info_launch_uris (GAppInfo *appinfo, + gboolean do_files; + GList *objs; + +- do_files = g_win32_app_info_supports_files (appinfo); ++ do_files = ! g_win32_app_info_supports_uris (appinfo); + + objs = NULL; + while (uris) +@@ -4305,7 +4366,8 @@ g_win32_app_info_launch_uris (GAppInfo *appinfo, + g_object_unref (file); + } + +- obj->uri = g_strdup (uris->data); ++ if (obj->file == NULL) ++ obj->uri = g_strdup (uris->data); + + objs = g_list_prepend (objs, obj); + uris = uris->next; +@@ -4341,11 +4403,13 @@ g_win32_app_info_launch (GAppInfo *appinfo, + { + file_or_uri *obj; + obj = g_new0 (file_or_uri, 1); +- obj->file = g_file_get_path (G_FILE (files->data)); + + if (do_uris) + obj->uri = g_file_get_uri (G_FILE (files->data)); + ++ if (obj->uri == NULL) ++ obj->file = g_file_get_path (G_FILE (files->data)); ++ + objs = g_list_prepend (objs, obj); + files = files->next; + } +@@ -4500,6 +4564,9 @@ g_app_info_get_default_for_type (const char *content_type, + GWin32AppInfoApplication *app; + GHashTableIter iter; + ++ if (g_strcmp0 (content_type, "inode/directory") == 0) ++ content_type = "Folder"; ++ + ext_down = g_utf8_casefold (content_type, -1); + + if (!ext_down) diff --git a/win32/patches/glib-gettext-fix.diff b/win32/patches/glib-gettext-fix.diff new file mode 100644 index 0000000..7f06934 --- /dev/null +++ b/win32/patches/glib-gettext-fix.diff @@ -0,0 +1,124 @@ +From 1d4e36a04b8ab49fafccb0bbdb74d4961b5eed58 Mon Sep 17 00:00:00 2001 +From: Руслан Ижбулатов +Date: Thu, 13 Jul 2017 01:42:13 +0000 +Subject: [PATCH] W32 - don't use gettext & gcov during gettext init + +Non-representable characters during UTF16->locale conversion +will cause gcov code to return an error, for which it will try +to use gettext, so that the error message is localized. + +If such call is made while gettext is being initialized +(there's a g_once_init_enter up the stack), the thread will hang forever. + +To solve this, use W32 API to do the UTF16->locale conversion +and don't use gettext when it returns an error. + +Also optimize g_win32_locale_filename_from_utf8() a bit, +as we need more UTF16 and less UTF8 now. + +https://bugzilla.gnome.org/show_bug.cgi?id=784579 +--- + glib/gwin32.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 60 insertions(+), 16 deletions(-) + +diff --git a/glib/gwin32.c b/glib/gwin32.c +index 81aab00..97a4808 100644 +--- a/glib/gwin32.c ++++ b/glib/gwin32.c +@@ -672,6 +672,49 @@ g_win32_get_windows_version (void) + return windows_version; + } + ++/* ++ * Doesn't use gettext (and gconv), preventing recursive calls when ++ * g_win32_locale_filename_from_utf8() is called during ++ * gettext initialization. ++ */ ++static gchar * ++special_wchar_to_locale_enoding (wchar_t *wstring) ++{ ++ int sizeof_output; ++ int wctmb_result; ++ char *result; ++ BOOL not_representable = FALSE; ++ ++ sizeof_output = WideCharToMultiByte (CP_ACP, ++ WC_NO_BEST_FIT_CHARS, ++ wstring, -1, ++ NULL, 0, ++ NULL, ++ ¬_representable); ++ ++ if (not_representable || ++ sizeof_output == 0 || ++ sizeof_output > MAX_PATH) ++ return NULL; ++ ++ result = g_malloc0 (sizeof_output + 1); ++ ++ wctmb_result = WideCharToMultiByte (CP_ACP, ++ WC_NO_BEST_FIT_CHARS, ++ wstring, -1, ++ result, sizeof_output + 1, ++ NULL, ++ ¬_representable); ++ ++ if (wctmb_result == sizeof_output && ++ not_representable == FALSE) ++ return result; ++ ++ g_free (result); ++ ++ return NULL; ++} ++ + /** + * g_win32_locale_filename_from_utf8: + * @utf8filename: a UTF-8 encoded filename. +@@ -704,26 +747,27 @@ g_win32_get_windows_version (void) + gchar * + g_win32_locale_filename_from_utf8 (const gchar *utf8filename) + { +- gchar *retval = g_locale_from_utf8 (utf8filename, -1, NULL, NULL, NULL); ++ gchar *retval; ++ wchar_t *wname; ++ ++ wname = g_utf8_to_utf16 (utf8filename, -1, NULL, NULL, NULL); ++ ++ if (wname == NULL) ++ return NULL; ++ ++ retval = special_wchar_to_locale_enoding (wname); + + if (retval == NULL) + { +- /* Conversion failed, so convert to wide chars, check if there +- * is a 8.3 version, and use that. +- */ +- wchar_t *wname = g_utf8_to_utf16 (utf8filename, -1, NULL, NULL, NULL); +- if (wname != NULL) +- { +- wchar_t wshortname[MAX_PATH + 1]; +- if (GetShortPathNameW (wname, wshortname, G_N_ELEMENTS (wshortname))) +- { +- gchar *tem = g_utf16_to_utf8 (wshortname, -1, NULL, NULL, NULL); +- retval = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL); +- g_free (tem); +- } +- g_free (wname); +- } ++ /* Conversion failed, so check if there is a 8.3 version, and use that. */ ++ wchar_t wshortname[MAX_PATH + 1]; ++ ++ if (GetShortPathNameW (wname, wshortname, G_N_ELEMENTS (wshortname))) ++ retval = special_wchar_to_locale_enoding (wshortname); + } ++ ++ g_free (wname); ++ + return retval; + } + +-- +libgit2 0.27.1 + diff --git a/win32/patches/gtk-parentheses.diff b/win32/patches/gtk-parentheses.diff new file mode 100644 index 0000000..c473d7c --- /dev/null +++ b/win32/patches/gtk-parentheses.diff @@ -0,0 +1,67 @@ +From 889a63dffc72c048502d0f7d2b26bfc8532462eb Mon Sep 17 00:00:00 2001 +From: John Lindgren +Date: Tue, 15 May 2018 21:47:12 -0400 +Subject: [PATCH] Fix compiler warnings with GCC 8.1. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +GCC 8.1 added some new warnings, including warning about parentheses +with no effect in variable declarations. GTK2 headers have a few of +these, which produce a lot of warnings in projects using GTK2. + +The warnings look like: +/usr/include/gtk-2.0/gtk/gtkfilechooserbutton.h:59:8: warning: +unnecessary parentheses in declaration of ‘__gtk_reserved1’ [-Wparentheses] + void (*__gtk_reserved1); + ^ + +Removing the parentheses is harmless and fixes the warnings. +--- + gtk/gtkfilechooserbutton.h | 14 +++++++------- + gtk/gtkstatusicon.h | 4 ++-- + 2 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/gtk/gtkfilechooserbutton.h b/gtk/gtkfilechooserbutton.h +index b3d9112cf9..fdacc4b6ec 100644 +--- a/gtk/gtkfilechooserbutton.h ++++ b/gtk/gtkfilechooserbutton.h +@@ -56,13 +56,13 @@ struct _GtkFileChooserButtonClass + + void (* file_set) (GtkFileChooserButton *fc); + +- void (*__gtk_reserved1); +- void (*__gtk_reserved2); +- void (*__gtk_reserved3); +- void (*__gtk_reserved4); +- void (*__gtk_reserved5); +- void (*__gtk_reserved6); +- void (*__gtk_reserved7); ++ void *__gtk_reserved1; ++ void *__gtk_reserved2; ++ void *__gtk_reserved3; ++ void *__gtk_reserved4; ++ void *__gtk_reserved5; ++ void *__gtk_reserved6; ++ void *__gtk_reserved7; + }; + + +diff --git a/gtk/gtkstatusicon.h b/gtk/gtkstatusicon.h +index 19dbd1cdeb..c45caca5ae 100644 +--- a/gtk/gtkstatusicon.h ++++ b/gtk/gtkstatusicon.h +@@ -73,8 +73,8 @@ struct _GtkStatusIconClass + gboolean keyboard_mode, + GtkTooltip *tooltip); + +- void (*__gtk_reserved1); +- void (*__gtk_reserved2); ++ void *__gtk_reserved1; ++ void *__gtk_reserved2; + }; + + GType gtk_status_icon_get_type (void) G_GNUC_CONST; +-- +2.22.0 + diff --git a/win32/patches/gtkicontheme.c.diff b/win32/patches/gtkicontheme.c.diff new file mode 100644 index 0000000..d23a44c --- /dev/null +++ b/win32/patches/gtkicontheme.c.diff @@ -0,0 +1,28 @@ +From bac94a7aaf2409d673c971e0733f292e74a6cec7 Mon Sep 17 00:00:00 2001 +From: John Lindgren +Date: Sun, 21 Jan 2018 02:09:14 -0500 +Subject: [PATCH] Fix incorrect optimization in find_builtin_icon(). + +When we found an icon with exactly the requested size, we'd stop +searching immediately (good), but we'd neglect to set the returned +min_difference to 0 (bad). This caused theme_lookup_icon() to +prefer other, potentially much worse, matches over the exact one. +--- + gtk/gtkicontheme.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c +index 532d94bee5..470158ceea 100644 +--- a/gtk/gtkicontheme.c ++++ b/gtk/gtkicontheme.c +@@ -3396,6 +3396,7 @@ find_builtin_icon (const gchar *icon_name, + + if (difference == 0) + { ++ min_difference = 0; + min_icon = default_icon; + break; + } +-- +2.16.0 + diff --git a/win32/patches/gtkmain.c.diff b/win32/patches/gtkmain.c.diff new file mode 100644 index 0000000..e7f0cf9 --- /dev/null +++ b/win32/patches/gtkmain.c.diff @@ -0,0 +1,17 @@ +--- gtk/gtkmain.c.0 2016-01-19 14:03:55.000000000 -0500 ++++ gtk/gtkmain.c 2018-05-30 22:19:18.138767100 -0400 +@@ -134,9 +134,13 @@ + g_free (root); + + /* gtk_localedir is passed to bindtextdomain() which isn't +- * UTF-8-aware. ++ * UTF-8-aware. Try to convert the path back to the legacy ++ * 8-bit locale. If that's impossible, there's not much we ++ * can do so just return the original build-time path. + */ + gtk_localedir = g_win32_locale_filename_from_utf8 (temp); ++ if (gtk_localedir == NULL) ++ gtk_localedir = g_strdup (GTK_LOCALEDIR); + g_free (temp); + } + return gtk_localedir; diff --git a/win32/patches/libcddb-1.3.diff b/win32/patches/libcddb-1.3.diff new file mode 100644 index 0000000..4449221 --- /dev/null +++ b/win32/patches/libcddb-1.3.diff @@ -0,0 +1,35 @@ +diff --git a/include/cddb/cddb_conn.h b/include/cddb/cddb_conn.h +index ada3cdd..dfff5bb 100644 +--- a/include/cddb/cddb_conn.h ++++ b/include/cddb/cddb_conn.h +@@ -55,6 +55,8 @@ typedef struct cddb_iconv_s *cddb_iconv_t; + */ + typedef struct cddb_conn_s cddb_conn_t; + ++#undef SEARCH_ALL /* namespace conflict with ntddchgr.h */ ++ + /** + * Which fields to use for the full text search is defined by one or + * more of the constants below. +diff --git a/lib/cddb_net.c b/lib/cddb_net.c +index 7adf37b..6e335b5 100644 +--- a/lib/cddb_net.c ++++ b/lib/cddb_net.c +@@ -228,7 +228,7 @@ int sock_vfprintf(cddb_conn_t *c, const char *format, va_list ap) + + /* Time-out enabled work-alikes */ + +-#ifdef HAVE_ALARM ++#if 0 + /* time-out jump buffer */ + static jmp_buf timeout_expired; + +@@ -241,7 +241,7 @@ static void alarm_handler(int signum) + + struct hostent *timeout_gethostbyname(const char *hostname, int timeout) + { +-#ifdef HAVE_ALARM ++#if 0 + struct hostent *he = NULL; + struct sigaction action; + struct sigaction old; diff --git a/win32/patches/libfaad-decoder.c.diff b/win32/patches/libfaad-decoder.c.diff new file mode 100644 index 0000000..5080a19 --- /dev/null +++ b/win32/patches/libfaad-decoder.c.diff @@ -0,0 +1,13 @@ +--- libfaad/decoder.c.0 2017-12-17 11:17:36.000000000 -0500 ++++ libfaad/decoder.c 2019-10-28 15:29:26.058465600 -0400 +@@ -53,10 +53,6 @@ + uint16_t dbg_count; + #endif + +-#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64 +-#include "win32_ver.h" +-#endif +- + /* static function declarations */ + static void* aac_frame_decode(NeAACDecStruct *hDecoder, + NeAACDecFrameInfo *hInfo, diff --git a/win32/patches/libmms-strndup.diff b/win32/patches/libmms-strndup.diff new file mode 100644 index 0000000..3c875ee --- /dev/null +++ b/win32/patches/libmms-strndup.diff @@ -0,0 +1,44 @@ +diff -ur libmms-0.6.4-orig/configure.in libmms-0.6.4/configure.in +--- libmms-0.6.4-orig/configure.in 2014-04-08 23:15:23 -0400 ++++ libmms-0.6.4/configure.in 2015-01-02 13:03:49 -0500 +@@ -14,6 +14,7 @@ + + dnl Checks for header files. + AC_CHECK_HEADERS([sys/socket.h netinet/in.h netdb.h windows.h winsock2.h]) ++AC_CHECK_FUNCS([strndup]) + + case $host in + *beos*) +diff -ur libmms-0.6.4-orig/src/uri.c libmms-0.6.4/src/uri.c +--- libmms-0.6.4-orig/src/uri.c 2014-04-02 10:22:58 -0400 ++++ libmms-0.6.4/src/uri.c 2015-01-02 13:07:13 -0500 +@@ -125,6 +125,29 @@ + #define ISSPACE(C) (((C) >= 9 && (C) <= 13) || (C) == ' ') + + ++/* Implement the strndup function. ++ Copyright (C) 2005 Free Software Foundation, Inc. ++ Written by Kaveh R. Ghazi . */ ++#ifndef HAVE_STRNDUP ++char * ++strndup (const char *s, size_t n) ++{ ++ char *result; ++ size_t len = strlen (s); ++ ++ if (n < len) ++ len = n; ++ ++ result = (char *) malloc (len + 1); ++ if (!result) ++ return 0; ++ ++ result[len] = '\0'; ++ return (char *) memcpy (result, s, len); ++} ++#endif ++ ++ + static int split_user_passwd(const char* in, char** user, char** passwd) + { + char *pass, *tmp = g_strdup(in); diff --git a/win32/patches/libmp3lame.sym.diff b/win32/patches/libmp3lame.sym.diff new file mode 100644 index 0000000..5c31040 --- /dev/null +++ b/win32/patches/libmp3lame.sym.diff @@ -0,0 +1,8 @@ +--- include/libmp3lame.sym.0 2017-09-06 15:33:35.000000000 -0400 ++++ include/libmp3lame.sym 2019-10-28 16:18:05.949994000 -0400 +@@ -1,5 +1,4 @@ + lame_init +-lame_init_old + lame_set_num_samples + lame_get_num_samples + lame_set_in_samplerate diff --git a/win32/patches/libsamplerate-0.1.diff b/win32/patches/libsamplerate-0.1.diff new file mode 100644 index 0000000..a95e81e --- /dev/null +++ b/win32/patches/libsamplerate-0.1.diff @@ -0,0 +1,13 @@ +diff --git a/examples/audio_out.c b/examples/audio_out.c +index 4ba8fb4..32548c8 100644 +--- a/examples/audio_out.c ++++ b/examples/audio_out.c +@@ -801,7 +801,7 @@ win32_close (AUDIO_OUT *audio_out) + static DWORD CALLBACK + win32_audio_out_callback (HWAVEOUT hwave, UINT msg, DWORD data, DWORD param1, DWORD param2) + { WIN32_AUDIO_OUT *win32_out ; +- int read_count, frame_count, k ; ++ int read_count, sample_count, frame_count, k ; + short *sptr ; + + /* diff --git a/win32/patches/neon-0.30.diff b/win32/patches/neon-0.30.diff new file mode 100644 index 0000000..f0f2b72 --- /dev/null +++ b/win32/patches/neon-0.30.diff @@ -0,0 +1,15 @@ +diff --git a/macros/neon.m4 b/macros/neon.m4 +index e051e94..2aa1605 100644 +--- a/macros/neon.m4 ++++ b/macros/neon.m4 +@@ -543,8 +543,8 @@ if test $ne_fmt_trycompile = yes; then + oflags="$CPPFLAGS" + # Consider format string mismatches as errors + CPPFLAGS="$CPPFLAGS -Wformat -Werror" +- dnl obscured for m4 quoting: "for str in d ld lld; do" +- for str in ne_spec l]ne_spec[ ll]ne_spec[; do ++ dnl obscured for m4 quoting: "for str in d ld lld I64d; do" ++ for str in ne_spec l]ne_spec[ ll]ne_spec[ I64]ne_spec[; do + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + $2 + #include ]], [[$1 i = 1; printf("%$str", i);]])], diff --git a/win32/patches/wavpack-4.80.diff b/win32/patches/wavpack-4.80.diff new file mode 100644 index 0000000..2e69c40 --- /dev/null +++ b/win32/patches/wavpack-4.80.diff @@ -0,0 +1,137 @@ +diff -ur wavpack-4.80.0-orig/cli/wavpack.c wavpack-4.80.0-mod/cli/wavpack.c +--- wavpack-4.80.0-orig/cli/wavpack.c 2016-03-11 19:15:55 -0500 ++++ wavpack-4.80.0-mod/cli/wavpack.c 2016-07-31 13:27:47 -0400 +@@ -41,9 +41,12 @@ + #if (defined(__GNUC__) || defined(__sun)) && !defined(_WIN32) + #include + #include +-#include +-#else ++#endif ++ ++#ifdef _MSC_VER + #include ++#else ++#include + #endif + + #ifdef _WIN32 +@@ -1441,7 +1444,7 @@ + FILE *infile; + int result; + +-#if defined(_WIN32) ++#if defined(_MSC_VER) + struct __timeb64 time1, time2; + #else + struct timeval time1, time2; +@@ -1611,7 +1614,7 @@ + } + } + +-#if defined(_WIN32) ++#if defined(_MSC_VER) + _ftime64 (&time1); + #else + gettimeofday(&time1,&timez); +@@ -2189,7 +2192,7 @@ + // compute and display the time consumed along with some other details of + // the packing operation, and then return WAVPACK_NO_ERROR + +-#if defined(_WIN32) ++#if defined(_MSC_VER) + _ftime64 (&time2); + dtime = time2.time + time2.millitm / 1000.0; + dtime -= time1.time + time1.millitm / 1000.0; +@@ -2452,7 +2455,7 @@ + double dtime; + int result; + +-#if defined(_WIN32) ++#if defined(_MSC_VER) + struct __timeb64 time1, time2; + #else + struct timeval time1, time2; +@@ -2596,7 +2599,7 @@ + } + } + +-#if defined(_WIN32) ++#if defined(_MSC_VER) + _ftime64 (&time1); + #else + gettimeofday(&time1,&timez); +@@ -2930,7 +2933,7 @@ + // compute and display the time consumed along with some other details of + // the packing operation, and then return WAVPACK_NO_ERROR + +-#if defined(_WIN32) ++#if defined(_MSC_VER) + _ftime64 (&time2); + dtime = time2.time + time2.millitm / 1000.0; + dtime -= time1.time + time1.millitm / 1000.0; +diff -ur wavpack-4.80.0-orig/cli/wvunpack.c wavpack-4.80.0-mod/cli/wvunpack.c +--- wavpack-4.80.0-orig/cli/wvunpack.c 2016-03-28 17:35:54 -0400 ++++ wavpack-4.80.0-mod/cli/wvunpack.c 2016-07-31 13:29:06 -0400 +@@ -31,10 +31,10 @@ + #endif + #endif + +-#if defined(__GNUC__) && !defined(_WIN32) +-#include +-#else ++#ifdef _MSC_VER + #include ++#else ++#include + #endif + + #include +@@ -933,7 +933,7 @@ + char error [80]; + FILE *outfile; + +-#if defined(_WIN32) ++#if defined(_MSC_VER) + struct __timeb64 time1, time2; + #else + struct timeval time1, time2; +@@ -1091,7 +1091,7 @@ + } + } + +-#if defined(_WIN32) ++#if defined(_MSC_VER) + _ftime64 (&time1); + #else + gettimeofday(&time1,&timez); +@@ -1325,7 +1325,7 @@ + // Compute and display the time consumed along with some other details of + // the unpacking operation (assuming there was no error). + +-#if defined(_WIN32) ++#if defined(_MSC_VER) + _ftime64 (&time2); + dtime = time2.time + time2.millitm / 1000.0; + dtime -= time1.time + time1.millitm / 1000.0; +diff -ur wavpack-4.80.0-orig/src/read_words.c wavpack-4.80.0-mod/src/read_words.c +--- wavpack-4.80.0-orig/src/read_words.c 2016-02-21 21:42:29 -0500 ++++ wavpack-4.80.0-mod/src/read_words.c 2016-07-31 13:23:34 -0400 +@@ -124,7 +124,7 @@ + wps->wvbits.bc += sizeof (*(wps->wvbits.ptr)) * 8; + } + +-#ifdef _WIN32 ++#ifdef _MSC_VER + _BitScanForward (&ones_count, ~wps->wvbits.sr); + #else + ones_count = __builtin_ctz (~wps->wvbits.sr); +@@ -399,7 +399,7 @@ + bs->bc += sizeof (*(bs->ptr)) * 8; + } + +-#ifdef _WIN32 ++#ifdef _MSC_VER + _BitScanForward (&ones_count, ~wps->wvbits.sr); + #else + ones_count = __builtin_ctz (~wps->wvbits.sr); -- cgit v1.2.3 From e8c3cd08f798c653f81a367ae30d04eedc7ed769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ukasik?= Date: Wed, 13 Oct 2021 21:45:42 +0200 Subject: Import audacious_4.0.5-2.debian.tar.xz [dgit import tarball audacious 4.0.5-2 audacious_4.0.5-2.debian.tar.xz] --- audacious-dev.install | 3 + audacious.install | 4 + changelog | 816 +++++++++++++++++++++++++++++++++++++++++++ control | 195 +++++++++++ copyright | 174 +++++++++ filtersym | 17 + gbp.conf | 7 + libaudcore5.install | 1 + libaudcore5.symbols | 446 +++++++++++++++++++++++ libaudgui5.install | 1 + libaudgui5.symbols | 78 +++++ libaudqt2.install | 1 + libaudqt2.symbols | 111 ++++++ libaudtag3.install | 1 + libaudtag3.symbols | 4 + patches/add-keywords.patch | 15 + patches/default-to-gtk.patch | 39 +++ patches/qt-option-man.patch | 25 ++ patches/series | 3 + rules | 36 ++ source/format | 1 + source/lintian-overrides | 5 + upstream/metadata | 2 + watch | 2 + 24 files changed, 1987 insertions(+) create mode 100644 audacious-dev.install create mode 100644 audacious.install create mode 100644 changelog create mode 100644 control create mode 100644 copyright create mode 100755 filtersym create mode 100644 gbp.conf create mode 100644 libaudcore5.install create mode 100644 libaudcore5.symbols create mode 100644 libaudgui5.install create mode 100644 libaudgui5.symbols create mode 100644 libaudqt2.install create mode 100644 libaudqt2.symbols create mode 100644 libaudtag3.install create mode 100644 libaudtag3.symbols create mode 100644 patches/add-keywords.patch create mode 100644 patches/default-to-gtk.patch create mode 100644 patches/qt-option-man.patch create mode 100644 patches/series create mode 100755 rules create mode 100644 source/format create mode 100644 source/lintian-overrides create mode 100644 upstream/metadata create mode 100644 watch diff --git a/audacious-dev.install b/audacious-dev.install new file mode 100644 index 0000000..90d8c98 --- /dev/null +++ b/audacious-dev.install @@ -0,0 +1,3 @@ +usr/include +usr/lib/*/*.so +usr/lib/*/pkgconfig diff --git a/audacious.install b/audacious.install new file mode 100644 index 0000000..943aa88 --- /dev/null +++ b/audacious.install @@ -0,0 +1,4 @@ +usr/bin +usr/share +contrib/*.appdata.xml usr/share/metainfo +contrib/thunar-sendto-audacious-playlist.desktop usr/share/Thunar/sendto diff --git a/changelog b/changelog new file mode 100644 index 0000000..1898aed --- /dev/null +++ b/changelog @@ -0,0 +1,816 @@ +audacious (4.0.5-2) unstable; urgency=medium + + [ Jelmer Vernooij ] + * Set upstream Repository/Repository-Browse fields. + + [ Mateusz Łukasik ] + * Merge requests for salsa: + - Describe Qt and GTK options in audacious manpage + - Fix some issues reported by lintian + * d/control: + - Bump Standards-Version to 4.6.0. + - Bump dh version to 13. + * Update symbols files - fix FTBFS with gcc-11. (Closes: #983974) + + -- Mateusz Łukasik Wed, 13 Oct 2021 21:45:42 +0200 + +audacious (4.0.5-1) unstable; urgency=medium + + * New upstream release. + + -- Andrej Shadura Wed, 06 Jan 2021 16:07:19 +0100 + +audacious (4.0.4-1) unstable; urgency=medium + + * New upstream bugfix release. + * Refresh patches. + + -- Andrej Shadura Wed, 03 Jun 2020 15:53:26 +0200 + +audacious (4.0.2-1) unstable; urgency=medium + + * New upstream release. + * Drop dependencies on libdbus-1-dev and libdbus-glib-1-dev + (Closes: #955874); depend on libglib2.0-dev explicitly instead. + * Drop explicit dependency on dbus. + * Bump Standards-Version to 4.5.0. + * Drop build dependency on libguess-dev. + + -- Andrej Shadura Sun, 19 Apr 2020 12:03:44 +0200 + +audacious (4.0-5) unstable; urgency=medium + + * Default to GTK interface. + + -- Andrej Shadura Sat, 18 Apr 2020 12:52:42 +0200 + +audacious (4.0-4) experimental; urgency=medium + + * Reintroduce the Qt 5 build: + - Build-depend on qtbase5-dev. + - Build libaudqt2 package. + - Refresh symbols. + + -- Andrej Shadura Mon, 23 Mar 2020 13:32:16 +0100 + +audacious (4.0-3) unstable; urgency=medium + + * Add lintian overrides. + * Update debian/copyright: + - Mention contrib/audacious.appdata.xml. + - Mention the license for buildsys. + * Install AppData and the Thunar sendto metadata. + + -- Andrej Shadura Mon, 23 Mar 2020 13:26:49 +0100 + +audacious (4.0-2) unstable; urgency=medium + + * Fix libaudcore5 symbols across architectures with regexes. + + -- Andrej Shadura Sun, 22 Mar 2020 23:49:12 +0100 + +audacious (4.0-1) unstable; urgency=medium + + [ Andrej Shadura ] + * New upstream release. + * Update the copyrights as per upstream commit fb0495c + * Refresh the uploaders list. + * Use debhelper compat 12. + * Update copyrights. + * Update and demangle symbols files. + * Build with GTK+ without Qt. + * Stop removing tinylock.h. + + [ Ondřej Nový ] + * Use debhelper-compat instead of debian/compat. + + -- Andrej Shadura Sun, 22 Mar 2020 22:19:48 +0100 + +audacious (3.10.1-1) unstable; urgency=medium + + * New upstream release. + + -- Andrej Shadura Wed, 20 Feb 2019 19:39:48 +0100 + +audacious (3.10-1) unstable; urgency=medium + + * License review (Closes: #883731). + - Drop use-system-licenses.patch. + - Update debian/copyright. + - Ship packaging under the same license as the upstream code. + + -- Andrej Shadura Sun, 28 Oct 2018 15:39:56 +0100 + +audacious (3.9-2) unstable; urgency=medium + + * Team upload. + + [ Simon Quigley ] + * Update symbols from build logs. + + [ Mattia Rizzolo ] + * Update symbol files to use c++|regex instead of hardcoding architecture + lists or using pkgkde-symbolshelper's subst. + + -- Mattia Rizzolo Fri, 25 Aug 2017 15:16:26 +0200 + +audacious (3.9-1) unstable; urgency=medium + + [ Mateusz Łukasik ] + * Team upload. + * New upstream release. (Closes: #864628, LP: #1670350) + * debian/patches: + - Drop use-system-libguess.patch + * debian/control: + - Switch from dbus-x11 to default-dbus-session-bus | dbus-session-bus + (Closes: #836078) + - Bump standards version to 3.9.8. (no changes needed) + * Drop qt5 interface: (Closes: #820472, LP: #1600318) + - debian/rules: Remove --enable-qt. + - Drop debian/libaudqt0.install. + - Drop debian/libaudqt0.symbols. + * Bump libralies sonames. + * Bump debhelper version to 10. + * debian/*.symbols - Update symbols to new version. + + [ Mattia Rizzolo ] + * Bump Standards-Version to 4.1.0, no changes needed. + * debian/libaudcore4.install: drop old file. + * debian/*.symbols: update symbols files after SONAME bumps. + + -- Mateusz Łukasik Thu, 24 Aug 2017 15:10:41 +0200 + +audacious (3.7.2-1) unstable; urgency=medium + + * Team upload. + + [ Sebastian Ramacher ] + * debian/control: Move library packages to Section libs. (Closes: #809268, + #809269, #809270) + + [ Alin Andrei ] + * Install .desktop file for Qt GUI. + + [ Andrew Shadura ] + * Build Qt5 GUI: + - Build-depend on qtbase5-dev + - Install libaudqt into a separate binary package. + + [ Mateusz Łukasik ] + * New upstream release. (Closes: #798501) + * Update symbols files for new version. + * Work around libaudqt package: + - Add install and symbols files. + * debian/patches: + - Add add-keywords.patch to provides keywords in desktop file. + - Add use-system-licenses.patch to use system licenses path. + - Add use-system-libguess.patch to use system libguess libraries. + * debian/rules: + - Use bindnow flag. + * debian/control: + - Bump standards version to 3.9.7. (no changes needed) + - Drop audacious-dbg package. + * Replace autotools-dev by dh-autoreconf. + * debian/watch: + - Bump to version 4. + + [ Nicholas D Steeves ] + * debian/libaudqt0.symbols: use c++ symbol pattern instead of arch-bits + + -- Mateusz Łukasik Thu, 07 Apr 2016 22:29:52 +0200 + +audacious (3.6.2-2) unstable; urgency=medium + + * Team upload. + * Upload to unstable. + + -- Sebastian Ramacher Sat, 19 Dec 2015 21:34:24 +0100 + +audacious (3.6.2-1) experimental; urgency=medium + + * Team upload. + + [ Mateusz Łukasik ] + * New upstream release. + * debian/control: + - Update VCS-URL's. + - Bump standards version to 3.9.6. (no changes needed) + - Switch depends from from libgtk-3-dev to libgtk2.0-dev - new version + drop GTK+3 interfaces. + * debian/rules: audacious.png now resides in images. + * Bump libaudcore version to 3 and update its symbols. + + [ Sebastian Ramacher ] + * debian/{control,libaud*.install,libaud*.symbols}: Split libaud* packages + into seperate binary packages. + * debian/control: + - Remove M-A: same from audacious-dbg. It depends on non M-A: same + packages. + - Remove obsolete Replaces and Provides. + - Drop libuchardet-dev from B-D. It is no longer needed. + * debian/menu: Removed (command-in-menu-file-and-desktop-file). + * debian/copyright: Update copyright years + + -- Sebastian Ramacher Sun, 13 Dec 2015 15:39:30 +0100 + +audacious (3.5-2) unstable; urgency=medium + + [ Sebastian Ramacher ] + * debian/control: Bump libguess-dev to >= 1.2~ in Build-Depends. Starting + with 3.5 audacious requires libguess 1.2. + + -- Andrew Shadura Tue, 22 Jul 2014 14:47:29 +0200 + +audacious (3.5-1) unstable; urgency=medium + + [ Alessio Treglia ] + * Bump Standards-Version. + + [ Alin Andrei ] + * New upstream release + * Removed libaudclient from control / install and libaudclient2.symbols + since libaudclient was dropped in Audacious 3.5 + * Updated symbols + * Rename binary package libaudcore1 to libaudcore2 because + of bumped major version + + [ Andrew Shadura ] + * Clean up the build in debian/clean. + + -- Alin Andrei Tue, 01 Jul 2014 08:27:36 +0200 + +audacious (3.4.3-1) unstable; urgency=low + + * New upstream release. Closes: #728502 + * Update symbols + + -- Jackson Doak Sat, 30 Nov 2013 08:12:12 +1100 + +audacious (3.4.1-1) unstable; urgency=low + + * Team upload. + * New upstream release. + * Avoid FTBFS on distclean failure. + * Refresh symbols. + * Remove myself from uploaders. + + -- Alessio Treglia Tue, 03 Sep 2013 09:40:44 +0100 + +audacious (3.4-1) unstable; urgency=low + + * New upstream release: + - Fix regression on reading m3u files containing empty + lines. (Closes: #705899) + * Tighten runtime dependency on audacious-plugins. (Closes: #708693) + * Update debian/copyright. + * Remove libmcs-dev from audacious-dev's Dependency field. + + -- Alessio Treglia Sun, 07 Jul 2013 16:46:38 +0100 + +audacious (3.3.4-2) unstable; urgency=low + + * Upload to unstable. + * Correct capitalization of such words as Winamp and + D-Bus. (Closes: #620862) + * Remove build-dependency on libmcs-dev. (Closes: #705098) + + -- Alessio Treglia Tue, 07 May 2013 09:32:25 +0200 + +audacious (3.3.4-1) experimental; urgency=low + + * New upstream release. + * Fix Vcs-* tags. + * Bump Standards. + + -- Alessio Treglia Tue, 05 Feb 2013 08:29:49 +0000 + +audacious (3.3.3-2) experimental; urgency=low + + * Move into the Multi-Arch domain. (Closes: #674492) + + -- Alessio Treglia Thu, 20 Dec 2012 20:53:12 +0000 + +audacious (3.3.3-1) experimental; urgency=low + + * New upstream release. + + -- Alessio Treglia Mon, 17 Dec 2012 20:38:10 +0000 + +audacious (3.3.2-1) experimental; urgency=low + + * New upstream release. + * Add myself to the Uploaders field. + + -- Alessio Treglia Mon, 10 Dec 2012 10:27:23 +0000 + +audacious (3.3.1-1) experimental; urgency=low + + * Team upload. + * New upstream release. + * Refresh debian/libaudcore1.symbols. + * Remove debian/patches/*, all patches do not apply anymore. + * Remove README from debian/audacious.docs, upstream doesn't + provide it anymore. + + -- Alessio Treglia Thu, 06 Sep 2012 17:35:38 +0200 + +audacious (3.2.3-1) unstable; urgency=low + + * Team upload. + * New upstream bugfix release. + + -- Alessio Treglia Sat, 02 Jun 2012 13:27:56 +0200 + +audacious (3.2.2-2) unstable; urgency=low + + * Team upload. + * Upload to unstable. + + -- Alessio Treglia Fri, 18 May 2012 13:11:45 +0200 + +audacious (3.2.2-1) experimental; urgency=low + + * Team upload. + + [ Alessio Treglia ] + * New upstream release. + * Update symbols file: + - Tag disappeared symbols as optional. + + [ Cyril LAVIER ] + * debian/rules : Removed the optimisation level tweaking for sparc. + + -- Alessio Treglia Wed, 16 May 2012 17:51:18 +0200 + +audacious (3.2.1-2) unstable; urgency=low + + * Team upload. + * Build with GTK3. (LP: #923052) + * Bump Standards. + + -- Alessio Treglia Thu, 01 Mar 2012 00:12:46 +0100 + +audacious (3.2.1-1) unstable; urgency=low + + * Team upload. + * New upstream bugfix release: + - Single-key playback shortcuts are back. + - PulseAudio output plugin sets buffer size correctly. + - Buildsystem cleanups. + - Translation updates. + - Other minor fixes. + * Set the -dbg package as Multi-Arch: same. + * Update watch file. + + -- Alessio Treglia Sun, 19 Feb 2012 18:29:45 +0100 + +audacious (3.2-2) unstable; urgency=low + + [ Cyril Lavier ] + * debian/rules: + + Changed the optimisation level for sparc. (Closes: #659820) + + [ Alessio Treglia ] + * Build for Multiarch. + + -- Cyril Lavier Fri, 17 Feb 2012 09:57:08 +0100 + +audacious (3.2-1) unstable; urgency=low + + * New upstream release. (Closes: #639374, #657081) + * debian/control: + + Removed all references to libmowgli + + Added libuchardet-dev and libguess-dev as build-dep + + Raised the Standards-Version to 3.9.2 + * debian/libaudclient2.symbols: symbols file updated + * debian/libaudcore1.symbols: symbols file updated + * debian/menu: command changed to "/usr/bin/audacious" + + -- Cyril Lavier Thu, 26 Jan 2012 22:54:40 +0100 + +audacious (2.4.4-1) unstable; urgency=low + + * New upstream release. + * Upload to unstable. + - Merge ld --no-add-needed FTBFS fix from experimental. (Closes: #618108) + * debian/patches/bp-audtag-debugging-output.patch: Refresh to make patch + apply without fuzz. + * debian/control: Improve package description, remove mention of codecs + not provided in -plugins package, add clarification on how support for + more codecs can be added through plugins. (Closes: #519160) + * debian/libaudcore1.symbols: Update according to changes in new upstream + release. + + -- Bilal Akhtar Mon, 04 Apr 2011 14:11:24 +0200 + +audacious (2.4.3-1) experimental; urgency=low + + * New upstream release. + * debian/patches/bp-audtag-debugging-output.patch: Refresh to make patch + apply without fuzz. + * debian/libaudcore1.symbols: Update symbols list. + + -- Bilal Akhtar Tue, 25 Jan 2011 14:59:58 +0100 + +audacious (2.4.2-1) experimental; urgency=low + + * New upstream release (Closes: #597179, LP: #579605, #625208). + - Fixes manpage suggests '-i newui' instead of '-i gtkui' (Closes: #588333). + - Builds with binutils-gold (Closes: #553935). + - Fix for writing equalizer presets (LP: #559287). + - Add the missing "playlist end reached" hook (LP: #625903). + - Fix messes up with configuration file while running (Closes: #471394). + - Display "year" of ogg files (Closes: #565194). + - Fix context menu is unusable with rolled up player near bottom of screen + (Closes: #584794). + - Rewritten crossfade plugin (Closes: #588335). + - Convert locale-encoded filenames to UTF-8 (Closes: #605963). + - Fix length calculation in mp3 plugin (Closes: #585048). + * Refer to versioned copyright file. + * Drop libaudid3tag2 package. It was removed by upstream. + * Drop all previous patches (all accepted upstream). + * Drop additional clean commands and image creation. + * Update symbols for libaudcore1 and libaudclient2. + * Use --with-buildstamp configure flag. + * Use --with autotools_dev instead of replacing the config files manually. + * Bump Standards-Version to 3.9.1 (no changes required). + * Bump libmowgli-dev to 0.7. + * Do not link against unused libraries (make dpkg-shlibdeps happy). + * Drop libglade2-dev and libsamplerate-dev from audacious-dev. + * Bump audacious-plugins dependency to 2.4.2. + * Add backported bp-audtag-debugging-output.patch: Implement debugging output + in audtag without linking to core's cfg variable. + * Put Audacious under the umbrella of the Multimedia Maintainers team. + * Update my email address. + + -- Benjamin Drung Wed, 29 Dec 2010 22:53:25 +0100 + +audacious (2.3-2) unstable; urgency=low + + [Chris Taylor] + * Update debian/copyright. + * Upload to unstable. + + [Benjamin Drung] + * Enable parallel build. + * Disable SSE2 on i386 (LP: #562713). + * Add new SVG icon created by Daniel Fore (LP: #563043). + * Rename icons from audacious2 to audacious. + * Install versionless symlinks audacious and audtool. + + -- Chris Taylor Mon, 10 May 2010 18:06:12 -0700 + +audacious (2.3-1) experimental; urgency=low + + [ Chris Taylor ] + * New uploader. + * New upstream release. + - (Closes: #559055, #531214, #497769, #534113, #567839, #491615, #500634) + - (Closes: #512911, #543449, #543561, #550550, #561826) + * Use source format 3.0 (quilt) + * Use dh7 in debian/rules + * Remove libsad* from packaging. + - Add replaces in debian/control + * Remove libaudutil* from packaging. + - Add replaces in debian/control. + * Add libaudtag and libaudgui to libaudcore1. + * Bump standards-version. + * Update debian/copyright. + + [ Benjamin Drung ] + * Bump libmcs-dev version to >= 0.7 (Closes: #508630). + * Change build id from UNSUPPORTED VERSION to package + (Closes: #572773). + * Add symbol files for libraries. + * Various cleanups. + + -- Chris Taylor Fri, 02 Apr 2010 21:37:21 +0000 + +audacious (2.1-1) unstable; urgency=low + + * New upstream release. + - Do not set the system volume at startup. (Closes: #531831) + - Don't crash on control-c in certain situations. (Closes: #531823) + - Fix 'stop after current song' behaviour. (Closes: #471553) + + * debian/patches/003-change-default-skin.patch: dropped. + * debian/control: Add dbus-x11 dependency. (Closes: #503427) + + -- William Pitcock Tue, 07 Jul 2009 20:29:37 -0500 + +audacious (2.0.1-1) unstable; urgency=low + + [ William Pitcock ] + * New upstream release. + * debian/patches/audacious-play-files-from-commandline.patch: dropped + * debian/patches/bugzilla-42.patch: dropped + + [ John Lindgren ] + * Fix improper behaviour when the file info dialog is closed. + (Closes: #495427) + * Fix crash with 'audtool help playback-seek-relative'. + (Closes: #512910) + * Fix some problems seeking while paused. + (Closes: #517692) + * Fix behaviour of -t argument when Audacious is not already running. + (Closes: #497602) + + [ Andrew O. Shadoura ] + * Include track number in MPRIS exported metadata. + (Closes: #514426) + + [ Benjamin Drung ] + * debian/patches/003-change-default-skin.patch: Corrected path + (skins -> Skins) + + -- William Pitcock Fri, 29 May 2009 21:25:03 -0500 + +audacious (1.5.1-4) unstable; urgency=medium + + [ Benjamin Drung ] + * debian/rules: Do not disable SSE2 on x86_64, because all x86_64 CPUs support + SSE2. + * debian/control: cosmetic improvements + + [ William Pitcock ] + * debian/patches/audacious-play-files-from-command-line.patch: Make adding + files from the command line work. Thanks Stefan Ott! (Closes: #491043) + * debian/patches/bugzilla-42.patch: Fix a bunch of crappy bugs in the + playlist code. (Closes: #491655, #491097). + + -- William Pitcock Fri, 29 Aug 2008 15:56:58 -0500 + +audacious (1.5.1-3) unstable; urgency=medium + + * Change dependency relations to make the package installable. + (Closes: #491699, #491910). + + -- William Pitcock Sun, 20 Jul 2008 23:10:13 -0500 + +audacious (1.5.1-2) unstable; urgency=medium + + * Build without SSE2 support where appropriate. + (Closes: #471061, #489037). + * Strengthen dependency on audacious-plugins to enforce correct + plugin version usage due to an ABI break. + (Closes: #489958, #486543, #489217). + * Make sure that libaudclient1 and libaudid3tag1 are updated to matching + versions so that the private interfaces match up correctly, by Depending + on them in audacious. + * debian/control: Bump to Standards-Version 3.8.0; no changes required. + + -- William Pitcock Thu, 17 Jul 2008 20:10:07 -0500 + +audacious (1.5.1-1) unstable; urgency=low + + * New upstream release, highlights include (Closes: #483095): + - On UNIX platforms, add a dbus dependency in audacious/audclient.pc. + (Closes: #469055) + - Remove Reload Plugins feature. + (Closes: #480202) + - Scaling feature has been reset back to the old scaling ratio. + (Closes: #471040) + * Move to team maintainance, like in audacious-plugins. + * Packaging improvements: + - debian/control: fix description of audacious-dev package, libaudacious + was dropped a long time ago and replaced with libaudclient. + (Closes: #475142) + - debian/control: make sure dependency relations cannot cause a cyclic + error. (Closes: #461511) + - debian/control: add audacious-dbg package. Please install this before + reporting segfaults, it makes correcting them much easier for me. + - debian/control: update my e-mail address + - debian/control, debian/rules, debian/patches/*: switch to Quilt. + - debian/patches/003-change-default-skin.patch: rebased against 1.5.1. + + -- William Pitcock Thu, 05 Jun 2008 23:07:17 -0500 + +audacious (1.5.0-2) unstable; urgency=low + + * Configure without SSE2 support (Closes: #471061). + + -- Adam Cécile (Le_Vert) Wed, 26 Mar 2008 09:45:26 +0100 + +audacious (1.5.0-1) unstable; urgency=low + + * New upstream release, highlights include: + - Provide the correct location for skins and configuration in + documentation. + (Closes: #430905) + * debian/control: + - Correct Build-Depends so that it won't try to incorrectly build on Etch. + (Closes: #466518) + - Bump Depends to force dependency on audacious-plugins 1.5. + * debian/copyright: major updates + + -- William Pitcock Thu, 13 Mar 2008 21:19:05 -0500 + +audacious (1.4.6-2) unstable; urgency=low + + * Fix D-Bus related breakage by depending on dbus itself. + (Closes: #460626, #452061, #460601) + + -- William Pitcock Sun, 03 Feb 2008 16:19:24 -0600 + +audacious (1.4.6-1) unstable; urgency=low + + * New upstream release. + * debian/patches/002-fix-eqf-import.patch: + - Upstream has included this in 1.4.6, dropped. + + -- William Pitcock Thu, 31 Jan 2008 14:45:57 -0600 + +audacious (1.4.5-2) unstable; urgency=low + + * debian/control: Improve the package descriptions a little. + * debian/patches/002-fix-eqf-import.dpatch: + - Fix EQF preset import/export. Patch by Cristi Magherusan + . (Closes: #457811) + * debian/patches/003-default-skin-change.dpatch: + - Switch the default skin back to the 1.3 skin, "Default1.3", because + some people complained too loudly. The people who complained loudly + are encouraged to supply a default skin which integrates better into + the Debian desktop than the 1.3 skin, as there have been complaints + with the 1.3 skin too. (Closes: #456557) + + -- William Pitcock Sun, 20 Jan 2008 16:59:07 -0600 + +audacious (1.4.5-1) unstable; urgency=low + + * New upstream release. + * Add gtk2-engines-pixbuf to runtime depends to satisfy policy violation + (Closes: #458083) + + -- William Pitcock Sat, 29 Dec 2007 15:38:17 -0600 + +audacious (1.4.4-1) unstable; urgency=low + + * New upstream release (Closes: #452884). + * Added William Pitcock (upstream) as co-maintainer. + * Bump Standards-Version to 3.7.3. + + -- Adam Cécile (Le_Vert) Tue, 11 Dec 2007 19:21:54 +0100 + +audacious (1.4.2-1) unstable; urgency=low + + * New upstream release. + * Bump audacious-plugins dependency (API fix). + + -- Adam Cécile (Le_Vert) Wed, 21 Nov 2007 21:30:35 +0100 + +audacious (1.4.0-1) unstable; urgency=low + + * New upstream release. + + -- Adam Cécile (Le_Vert) Tue, 13 Nov 2007 11:20:10 +0100 + +audacious (1.4.0~beta4-1) unstable; urgency=low + + * New upstream release: + - Add 000-Disable_Makefile_silent_output patch (new build system), + - Add 001-libaudid3tag_is_a_public_library.dpatch patch, + - Drop libaudaciousX package (library dropped upstream), + - Add libaudid3tagX, libauclientX packages, + - Add DBUS build-depends. + * Update debian/watch. + * Rewrite PNG/XPM icons handling; all sizes are now generated. + * Use new dpkg 'homepage' field. + + -- Adam Cécile (Le_Vert) Sun, 28 Oct 2007 21:23:29 +0100 + +audacious (1.3.2-5) unstable; urgency=low + + * Build with --enable-samplerate (Closes: #437428). + * Fix debian/watch. + * Update debian/menu to current policy. + * Fix .desktop to fit current FreeDesktop specifications. + + -- Adam Cécile (Le_Vert) Thu, 04 Oct 2007 14:40:02 +0200 + +audacious (1.3.2-4) unstable; urgency=low + + * debian/rules: install target should depends on build (Closes: #425205). + + -- Adam Cécile (Le_Vert) Tue, 22 May 2007 13:55:18 +0200 + +audacious (1.3.2-3) unstable; urgency=low + + * Add missing libmcs-dev (>= 0.4.1) depends to audacious-dev (Closes: #420592). + * Audacious now recommends unzip (winamp skins) (Closes: #421923). + + -- Adam Cécile (Le_Vert) Wed, 09 May 2007 09:24:20 +0200 + +audacious (1.3.2-2) unstable; urgency=low + + * Add dh_desktop call to run update-desktop-database (Closes: #420416). + * Merge upstream patch against doc to reflect use of XDG paths (Closes: #420106). + + -- Adam Cécile (Le_Vert) Mon, 23 Apr 2007 09:14:52 +0200 + +audacious (1.3.2-1) unstable; urgency=low + + * New upstream release. + + -- Adam Cécile (Le_Vert) Sat, 14 Apr 2007 19:41:37 +0200 + +audacious (1.3.1-3) unstable; urgency=low + + * Uploading to unstable (Closes: #416997, #416415) + + -- Adam Cécile (Le_Vert) Fri, 13 Apr 2007 12:01:43 +0200 + +audacious (1.3.1-2) experimental; urgency=low + + * Add missing libaudid3tag.so to libaudacious5 package. + + -- Adam Cécile (Le_Vert) Tue, 20 Mar 2007 10:51:30 +0100 + +audacious (1.3.1-1) experimental; urgency=low + + * New upstream release. + - HTTP support reimplemented through curl (Closes: #409303). + - Improve paranormal plugin (Closes: #410573). + - Charset detection has been improved, enable it! + * Update debian/watch. + * Remove 000-Fix_lock_up_with_invalid_playlist patch, fixed upstream. + * Add build-depends on libmcs-dev (>= 0.4.1), mcs manages audacious' conf file. + * $(MAKE) distclean failure is not fatal anymore. + * Bump libaudacious so-name (major: 5). + * debian/rules target's dependencies adjusted to avoid configure run twice. + * Update debian/copyright. + * Add versionned dependency on -plugins packages. + + -- Adam Cécile (Le_Vert) Sat, 10 Mar 2007 22:59:33 +0100 + +audacious (1.2.2-4) unstable; urgency=low + + * Add a %U to the Exec entry in audacious.desktop (Closes: #410755). + + -- Adam Cécile (Le_Vert) Tue, 13 Feb 2007 13:58:12 +0100 + +audacious (1.2.2-3) unstable; urgency=low + + * Add quilt dependency as patch system. + * New patch: 000-Fix_lock_up_with_invalid_playlist (Closes: #403221). + + -- Adam Cécile (Le_Vert) Fri, 15 Dec 2006 21:37:44 +0100 + +audacious (1.2.2-2) unstable; urgency=low + + * Split again libaudacious4 in separate package to get rid of circular + dependencies (Closes: #401353). + * Remove audtool manpage, merged in upstream. + + -- Adam Cécile (Le_Vert) Sun, 3 Dec 2006 10:49:22 +0100 + +audacious (1.2.2-1) unstable; urgency=low + + * New upstream release. + + -- Adam Cécile (Le_Vert) Sun, 26 Nov 2006 23:24:50 +0100 + +audacious (1.2.1-3) unstable; urgency=low + + * Touch mk/rules.mk to avoid clean runs configure (Closes: #397794). + + -- Adam Cécile (Le_Vert) Mon, 20 Nov 2006 08:21:12 +0100 + +audacious (1.2.1-2) unstable; urgency=low + + * Remove audacious-dev rdepends on audacious to avoid circular dependency + when building audacious-plugins. + * Install doc in audacious-dev package as it doesn't depend on audacious + anymore. + + -- Adam Cécile (Le_Vert) Sun, 19 Nov 2006 17:47:38 +0100 + +audacious (1.2.1-1) unstable; urgency=low + + * New upstream release. + * Remove all plugins related stuff, upstream splitted sources. + * Remove libaudacious. Now create audacious and audacious-dev packages. + + -- Adam Cécile (Le_Vert) Thu, 2 Nov 2006 20:00:08 +0100 + +audacious (1.1.2-3) unstable; urgency=low + + * Install audacious.pc in libaudacious-dev (Closes: #396547). + * Remove linux-any from build-depends, deprecated. + * Write audtool manpage. + * Add debian/watch. + + -- Adam Cécile (Le_Vert) Wed, 1 Nov 2006 18:12:58 +0100 + +audacious (1.1.2-2) unstable; urgency=low + + * Fix FTBS on systems which do not use ALSA (Closes: #395838). + * Add menu entry (Closes: #395571). + * Disable amidi-plug (Closes: #395848). + + -- Adam Cécile (Le_Vert) Sat, 28 Oct 2006 04:18:33 +0200 + +audacious (1.1.2-1) unstable; urgency=low + + * Initial release (Closes: #360524). + + -- Adam Cécile (Le_Vert) Fri, 1 Sep 2006 20:56:15 +0200 diff --git a/control b/control new file mode 100644 index 0000000..4362818 --- /dev/null +++ b/control @@ -0,0 +1,195 @@ +Source: audacious +Section: sound +Priority: optional +Maintainer: Debian Multimedia Maintainers +Uploaders: + Andrej Shadura , + Mateusz Łukasik +Build-Depends: + debhelper-compat (= 13), + imagemagick, + libglib2.0-dev, + libgtk2.0-dev, + librsvg2-bin, + qtbase5-dev +Standards-Version: 4.6.0 +Homepage: https://www.audacious-media-player.org/ +Vcs-Browser: https://salsa.debian.org/multimedia-team/audacious +Vcs-Git: https://salsa.debian.org/multimedia-team/audacious.git + +Package: audacious +Architecture: any +Depends: + audacious-plugins (>= ${source:Upstream-Version}), + default-dbus-session-bus | dbus-session-bus | dbus-x11, + gtk2-engines-pixbuf, + libaudcore5 (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Recommends: + unzip +Description: small and fast audio player which supports lots of formats + Audacious is a fork of beep-media-player which supports Winamp skins + and many codecs. + . + In the default install, the following codecs are supported: + . + * MP3 + * Ogg Vorbis / Theora + * AAC and AAC+ + * FLAC + * ALAC + * Windows Media (WMA) + * WAVE + . + Additionally, Audacious is extendable through plugins, and contains + other useful features like LIRC support. Support for many more codecs + can also be added through plugins. + . + This package contains the core player and its localization. + +Package: audacious-dev +Section: libdevel +Architecture: any +Multi-Arch: same +Depends: + libaudcore5 (= ${binary:Version}), + libaudgui5 (= ${binary:Version}), + libaudtag3 (= ${binary:Version}), + libaudqt2 (= ${binary:Version}), + libglib2.0-dev, + libgtk2.0-dev, + qtbase5-dev, + ${misc:Depends} +Description: audacious development files + Audacious is a fork of beep-media-player which supports Winamp skins + and many codecs. + . + In the default install, the following codecs are supported: + . + * MP3 + * Ogg Vorbis / Theora + * AAC and AAC+ + * FLAC + * ALAC + * Windows Media (WMA) + * WAVE + . + Additionally, Audacious is extendable through plugins, and contains + other useful features like LIRC support. Support for many more codecs + can also be added through plugins. + . + This package contains the development libraries and header files + required for developing components for audacious. + . + Please note that this package no longer contains libaudacious, as + libaudacious was dropped in Audacious 1.4. + +Package: libaudcore5 +Section: libs +Architecture: any +Multi-Arch: same +Depends: + ${misc:Depends}, + ${shlibs:Depends} +Description: audacious core engine library + Audacious is a fork of beep-media-player which supports Winamp skins + and many codecs. + . + In the default install, the following codecs are supported: + . + * MP3 + * Ogg Vorbis / Theora + * AAC and AAC+ + * FLAC + * ALAC + * Windows Media (WMA) + * WAVE + . + Additionally, Audacious is extendable through plugins, and contains + other useful features like LIRC support. Support for many more codecs + can also be added through plugins. + . + This package contains a library which provides core functionality + of Audacious. + +Package: libaudgui5 +Section: libs +Architecture: any +Multi-Arch: same +Depends: + ${misc:Depends}, + ${shlibs:Depends} +Description: audacious media player (libaudgui shared library) + Audacious is a fork of beep-media-player which supports Winamp skins + and many codecs. + . + In the default install, the following codecs are supported: + . + * MP3 + * Ogg Vorbis / Theora + * AAC and AAC+ + * FLAC + * ALAC + * Windows Media (WMA) + * WAVE + . + Additionally, Audacious is extendable through plugins, and contains + other useful features like LIRC support. Support for many more codecs + can also be added through plugins. + . + This package provides the libaudgui shared library. + +Package: libaudtag3 +Section: libs +Architecture: any +Multi-Arch: same +Depends: + ${misc:Depends}, + ${shlibs:Depends} +Description: audacious media player (libaudtag shared library) + Audacious is a fork of beep-media-player which supports Winamp skins + and many codecs. + . + In the default install, the following codecs are supported: + . + * MP3 + * Ogg Vorbis / Theora + * AAC and AAC+ + * FLAC + * ALAC + * Windows Media (WMA) + * WAVE + . + Additionally, Audacious is extendable through plugins, and contains + other useful features like LIRC support. Support for many more codecs + can also be added through plugins. + . + This package provides the libaudtag shared library. + +Package: libaudqt2 +Section: libs +Architecture: any +Multi-Arch: same +Depends: + ${misc:Depends}, + ${shlibs:Depends} +Description: audacious media player (libaudqt shared library) + Audacious is a fork of beep-media-player which supports Winamp skins + and many codecs. + . + In the default install, the following codecs are supported: + . + * MP3 + * Ogg Vorbis / Theora + * AAC and AAC+ + * FLAC + * ALAC + * Windows Media (WMA) + * WAVE + . + Additionally, Audacious is extendable through plugins, and contains + other useful features like LIRC support. Support for many more codecs + can also be added through plugins. + . + This package provides the libaudqt shared library. diff --git a/copyright b/copyright new file mode 100644 index 0000000..90dab89 --- /dev/null +++ b/copyright @@ -0,0 +1,174 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: audacious +Source: https://audacious-media-player.org/ + +Files: * +Copyright: + 2005-2020 Audacious Development Team: + John Lindgren , + Michał Lipski, + Ariadne Conill , + George Averill , + René Bertin, + Christian Birchinger, + Ralf Ertzinger, + Michael Färber <0102@gmx.at>, + Matti Hämäläinen, + Michael Hanselmann, + Jussi Judin, + Anders Johansson, + Thomas Lange, + Giacomo Lozito , + Tomasz Moń , + Ben Tucker , + Tony Vroon , + Yoshiki Yazawa , + Eugene Zagidullin , + and others + 2003-2004 BMP Development Team + 1998-2003 XMMS Development Team +License: BSD-2-clause + +Files: buildsys.mk.in +Copyright: 2007—2017 Jonathan Schleifer +License: ISC + +Files: contrib/audacious.appdata.xml +Copyright: 2015-2020 Audacious Development Team +License: CC0 + +Files: src/libaudtag/* +Copyright: + 2009-2010, Paula Stanciu, + John Lindgren, + Tony Vroon, + Ariadne Conill, + Mikael Magnusson, + Michał Lipski +License: BSD-2-clause + +Files: po/* +Copyright: + 2012 Ibrahim Saed + 2015 Rached Noureddine + 2016 Abouzakaria Kov + 2009 Darafei Praliaskouski + 2012—2015, 2017 Mikalai Udodau + 2014 Aleh Mazok + 2013, 2015—2017 Радослав Иванов + 2012, 2014—2015 Kiril Kirilov + 2007—2008 Ernest Adrogué + 2015—2016 David Surroca Estrada + 2016—2018 Robert Antoni Buj Gelonch + 2011 Ruei-Yuan Lu + 2004 Thierry Vignaud + 2007—2010 Petr Písař + 2014, 2017 Petr Šimáček + 2016 Roman Horník + 2013—2014, 2016 Joe Hansen + 2011, 2014—2015 Thomas Lange + 2004 Edward Brocklesby + 2006 Stavros Giannouris + 2006 Stathis Kamperis + 2011—2014 Γιάννης Ανθυμίδης + 2006 Gustavo D. Vrangjes, + 2008 Jeki SInneo Leinos + 2007 Strahinja Kustudić + 2007 Diego Petteno + 2004 Rimas Kudelis + 2007 Jovan Naumovski + 2006 Tony Vroon + 2006 Wojciech Myrda + 2010 Luis Picciochi + 2007 Cristi Măgherușan + 2007 Alexander Orlov + 2007-2010 Andrej Herceg + 2007 Strahinja Kustudić + 2005 Mykola Lynnyk + and others +License: BSD-2-clause + +Files: debian/* +Copyright: + 2006—2010 Adam Cécile (Le_Vert) + 2008—2009 Ariadne Conill + 2010 Chris Taylor + 2010 Benjamin Drung + 2012—2014 Alessio Treglia + 2014, 2015 Sebastian Ramacher + 2014, 2016, 2018, 2020 Andrej Shadura + 2015—2017 Mateusz Łukasik + 2016, 2017 Nicholas D Steeves + 2017 Mattia Rizzolo +License: BSD-2-clause + +Files: + src/libguess/guess.scm + src/libguess/guess_impl.c + src/libguess/libguess.h +Copyright: 2000-2003, Shiro Kawai +License: BSD-3-clause + +License: BSD-2-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + . + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + provided with the distribution. + . + This software is provided "as is" and without any warranty, express or + implied. In no event shall the authors be liable for any damages arising from + the use of this software. + +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + . + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + . + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + . + 3. Neither the name of the authors nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License: CC0 + On Debian systems, the complete text of the CC0 1.0 Universal + license can be found in ‘/usr/share/common-licenses/CC0-1.0’. + +License: ISC + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice is present in all copies. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. diff --git a/filtersym b/filtersym new file mode 100755 index 0000000..8248b47 --- /dev/null +++ b/filtersym @@ -0,0 +1,17 @@ +#!/usr/bin/gawk -f + +# demangle symbols file + +/^lib/ + +/^ \(/ + +function demangle(sym) { + split(sym, parts, /@/) + "c++filt -n " parts[1] | getline demangled + return demangled "@" parts[2] +} + +/^ _Z/ { + print " (c++)\"" demangle($1) "\" " $2 +} diff --git a/gbp.conf b/gbp.conf new file mode 100644 index 0000000..2e081f6 --- /dev/null +++ b/gbp.conf @@ -0,0 +1,7 @@ +[DEFAULT] +debian-branch = master +pristine-tar = True +compression = bzip2 + +[dch] +meta = True diff --git a/libaudcore5.install b/libaudcore5.install new file mode 100644 index 0000000..b51b0e5 --- /dev/null +++ b/libaudcore5.install @@ -0,0 +1 @@ +usr/lib/*/libaudcore.so.* diff --git a/libaudcore5.symbols b/libaudcore5.symbols new file mode 100644 index 0000000..4bb8a01 --- /dev/null +++ b/libaudcore5.symbols @@ -0,0 +1,446 @@ +libaudcore.so.5 libaudcore5 #MINVER# + (c++)"aud_resume()@Base" 3.8 + (c++)"int_to_str(int)@Base" 3.8 + (c++)"str_concat(std::initializer_list const&)@Base" 3.8 + (c++)"str_printf(char const*, ...)@Base" 3.8 + (c++)"str_to_int(char const*)@Base" 3.8 + (c++)"aud_cleanup()@Base" 3.8 + (c++)"aud_get_int(char const*, char const*)@Base" 3.8 + (c++)"aud_get_str(char const*, char const*)@Base" 3.8 + (c++)"aud_set_int(char const*, char const*, int)@Base" 3.8 + (c++)"aud_set_str(char const*, char const*, char const*)@Base" 3.8 + (c++)"aud_ui_show(bool)@Base" 3.8 + (c++)"event_queue(char const*, void*, void (*)(void*))@Base" 3.8 + (c++)"str_compare(char const*, char const*)@Base" 3.8 + (c++)"str_convert(char const*, int, char const*, char const*)@Base" 3.8 + (c++)"str_to_utf8(StringBuf&&)@Base" 3.8 + (c++)"str_to_utf8(char const*, int)@Base" 3.8 + (c++)"str_tolower(char const*)@Base" 3.8 + (c++)"str_toupper(char const*)@Base" 3.9 + (c++|regex)"^str_vprintf\(char const\*, (__va_list_tag\*?|char\*|std::__va_list|void\*)\)@Base$" 3.9 + (c++|optional)"std::unique_lock::unlock()@Base" 4.0.5 + (c++|optional)"std::_Function_base::~_Function_base()@Base" 4.0.5 + (c++|optional|regex)"std::once_flag::.*@Base" 4.0.5 + (c++)"strcmp_safe(char const*, char const*, int)@Base" 3.8 + (c++)"tiny_unlock(char*)@Base" 3.8 + (c++)"aud_art_data(AudArtItem const*)@Base" 3.9 + (c++)"aud_art_file(AudArtItem const*)@Base" 3.9 + (c++)"aud_get_bool(char const*, char const*)@Base" 3.8 + (c++)"aud_get_path(AudPath)@Base" 3.8 + (c++)"aud_set_bool(char const*, char const*, bool)@Base" 3.8 + (c++)"audio_to_int(float const*, void*, int, int)@Base" 3.8 + (c++)"mainloop_run()@Base" 3.8 + (c++)"timer_remove(TimerRate, void (*)(void*), void*)@Base" 3.8 + (c++)"aud_art_unref(AudArtItem*)@Base" 3.9 + (c++)"aud_drct_play()@Base" 3.8 + (c++)"aud_drct_seek(int)@Base" 3.8 + (c++)"aud_drct_stop()@Base" 3.8 + (c++)"aud_init_i18n()@Base" 3.8 + (c++)"audio_amplify(float*, int, int, StereoVolume)@Base" 3.8 + (c++)"audio_amplify(float*, int, int, float const*)@Base" 3.8 + (c++)"double_to_str(double)@Base" 3.8 + (c++)"mainloop_quit()@Base" 3.8 + (c++)"str_calc_hash(char const*)@Base" 3.8 + (c++)"str_to_double(char const*)@Base" 3.8 + (c++)"str_to_locale(char const*, int)@Base" 3.8 + (c++)"strcmp_nocase(char const*, char const*, int)@Base" 3.8 + (c++)"strstr_nocase(char const*, char const*)@Base" 3.8 + (c++)"uri_construct(char const*, char const*)@Base" 3.8 + (c++)"aud_drct_pause()@Base" 3.8 + (c++)"aud_get_double(char const*, char const*)@Base" 3.8 + (c++)"aud_leak_check()@Base" 3.8 + (c++)"aud_set_double(char const*, char const*, double)@Base" 3.8 + (c++)"audio_from_int(void const*, int, float*, int)@Base" 3.8 + (c++)"filename_build(std::initializer_list const&)@Base" 3.8 + (c++)"hook_associate(char const*, void (*)(void*, void*), void*)@Base" 3.8 + (c++)"str_insert_int(StringBuf&, int, int)@Base" 4.0 + (c++)"strlen_bounded(char const*, int)@Base" 3.8 + (c++)"tiny_lock_read(unsigned short*)@Base" 3.8 + (c++)"uri_get_scheme(char const*)@Base" 3.8 + (c++)"uri_to_display(char const*)@Base" 3.8 + (c++)"aud_art_request(char const*, int, bool*)@Base" 3.9 + (c++)"aud_drct_pl_add(char const*, int)@Base" 3.8 + (c++)"aud_eq_get_band(int)@Base" 3.8 + (c++)"aud_eq_set_band(int, double)@Base" 3.8 + (c++)"aud_history_add(char const*)@Base" 3.8 + (c++)"aud_history_get(int)@Base" 3.8 + (c++)"aud_plugin_list(PluginType)@Base" 3.8 + (c++)"aud_toggle_bool(char const*, char const*)@Base" 3.9 + (c++)"aud_ui_is_shown()@Base" 3.8 + (c++)"audio_interlace(void const* const*, int, int, void*, int)@Base" 3.8 + (c++)"audio_soft_clip(float*, int)@Base" 3.8 + (c++)"filename_expand(StringBuf&&)@Base" 3.8 + (c++)"filename_to_uri(char const*)@Base" 3.8 + (c++)"hook_dissociate(char const*, void (*)(void*, void*), void*)@Base" 3.8 + (c++|regex)"^str_format_time\((long|long long)\)@Base$" 3.8 + (c++)"str_from_locale(char const*, int)@Base" 3.8 + (c++)"tiny_lock_write(unsigned short*)@Base" 3.8 + (c++)"uri_deconstruct(char const*, char const*)@Base" 4.0 + (c++)"uri_to_filename(char const*, bool)@Base" 3.8 + (c++)"aud_drct_pl_next()@Base" 3.8 + (c++)"aud_drct_pl_open(char const*)@Base" 3.8 + (c++)"aud_drct_pl_prev()@Base" 3.8 + (c++)"aud_eq_get_bands(double*)@Base" 3.8 + (c++)"aud_eq_set_bands(double const*)@Base" 3.8 + (c++)"aud_get_instance()@Base" 3.8 + (c++)"aud_output_reset(OutputReset)@Base" 3.8 + (c++)"aud_set_instance(int)@Base" 3.8 + (c++)"int_array_to_str(int const*, int)@Base" 3.8 + (c++)"str_replace_char(char*, char, char)@Base" 3.8 + (c++)"str_to_int_array(char const*, int*, int)@Base" 3.8 + (c++)"str_tolower_utf8(char const*)@Base" 3.8 + (c++)"str_toupper_utf8(char const*)@Base" 3.9 + (c++)"tiny_unlock_read(unsigned short*)@Base" 3.8 + (c++)"aud_drct_get_info(int&, int&, int&)@Base" 3.8 + (c++)"aud_drct_get_time()@Base" 3.8 + (c++)"aud_file_read_tag(char const*, PluginHandle*, VFSFile&, Tuple&, Index*, String*)@Base" 3.8 + (c++)"aud_history_clear()@Base" 4.0 + (c++)"aud_plugin_enable(PluginHandle*, bool)@Base" 3.8 + (c++)"aud_ui_show_error(char const*)@Base" 3.8 + (c++)"audio_deinterlace(void const*, int, int, void* const*, int)@Base" 3.8 + (c++)"filename_contract(StringBuf&&)@Base" 3.8 + (c++)"filename_get_base(char const*)@Base" 3.8 + (c++)"index_to_str_list(Index const&, char const*)@Base" 3.8 + (c++)"str_append_printf(StringBuf&, char const*, ...)@Base" 4.0 + (c++)"str_insert_double(StringBuf&, int, double)@Base" 4.0 + (c++)"str_list_to_index(char const*, char const*)@Base" 3.8 + (c++)"tiny_unlock_write(unsigned short*)@Base" 3.8 + (c++)"uri_get_extension(char const*)@Base" 3.8 + (c++)"aud_custom_infowin(char const*, PluginHandle*)@Base" 3.8 + (c++)"aud_drct_get_ready()@Base" 3.8 + (c++)"aud_drct_get_title()@Base" 3.8 + (c++)"aud_drct_get_tuple()@Base" 3.8 + (c++)"aud_visualizer_add(Visualizer*)@Base" 3.8 + (c++)"event_queue_cancel(char const*, void*)@Base" 3.8 + (c++)"filename_normalize(StringBuf&&)@Base" 3.8 + (c++|regex)"^str_append_vprintf\(StringBuf&, char const\*, (__va_list_tag\*?|char\*|std::__va_list|void\*)\)@Base" 4.0 + (c++)"str_decode_percent(char const*, int)@Base" 3.8 + (c++)"str_encode_percent(char const*, int)@Base" 3.8 + (c++)"strstr_nocase_utf8(char const*, char const*)@Base" 3.8 + (c++)"aud_drct_get_length()@Base" 3.8 + (c++)"aud_drct_get_paused()@Base" 3.8 + (c++)"aud_drct_get_volume()@Base" 3.8 + (c++)"aud_drct_play_pause()@Base" 3.8 + (c++)"aud_drct_set_volume(StereoVolume)@Base" 3.8 + (c++)"aud_eq_apply_preset(EqualizerPreset const&)@Base" 3.8 + (c++)"aud_eq_read_presets(char const*)@Base" 3.8 + (c++)"aud_plugin_get_name(PluginHandle*)@Base" 3.8 + (c++)"aud_plugin_get_type(PluginHandle*)@Base" 3.8 + (c++)"aud_plugin_menu_add(AudMenuID, void (*)(), char const*, char const*)@Base" 3.8 + (c++)"double_array_to_str(double const*, int)@Base" 3.8 + (c++)"filename_get_parent(char const*)@Base" 3.8 + (c++)"inifile_write_entry(VFSFile&, char const*, char const*)@Base" 3.8 + (c++)"str_compare_encoded(char const*, char const*)@Base" 3.8 + (c++)"str_to_double_array(char const*, double*, int)@Base" 3.8 + (c++)"aud_drct_get_playing()@Base" 3.8 + (c++)"aud_drct_pl_add_list(Index&&, int)@Base" 3.8 + (c++)"aud_eq_update_preset(EqualizerPreset&)@Base" 3.8 + (c++)"aud_eq_write_presets(Index const&, char const*)@Base" 3.8 + (c++)"aud_file_write_tuple(char const*, PluginHandle*, Tuple const&)@Base" 3.8 + (c++)"aud_load_preset_file(EqualizerPreset&, VFSFile&)@Base" 3.8 + (c++)"aud_plugin_add_watch(PluginHandle*, bool (*)(PluginHandle*, void*), void*)@Base" 3.8 + (c++)"aud_plugin_by_header(void const*)@Base" 3.8 + (c++)"aud_plugin_has_about(PluginHandle*)@Base" 3.8 + (c++)"aud_save_preset_file(EqualizerPreset const&, VFSFile&)@Base" 3.8 + (c++)"uri_get_display_base(char const*)@Base" 4.0 + (c++)"aud_drct_get_filename()@Base" 3.8 + (c++)"aud_drct_get_position()@Base" 3.8 + (c++)"aud_drct_pl_open_list(Index&&)@Base" 3.8 + (c++)"aud_drct_pl_open_temp(char const*)@Base" 3.8 + (c++)"aud_file_find_decoder(char const*, bool, VFSFile&, String*)@Base" 3.8 + (c++)"aud_get_headless_mode()@Base" 3.8 + (c++)"aud_get_mainloop_type()@Base" 3.8 + (c++)"aud_plugin_get_header(PluginHandle*)@Base" 3.8 + (c++)"aud_set_headless_mode(bool)@Base" 3.8 + (c++)"aud_set_mainloop_type(MainloopType)@Base" 3.8 + (c++)"aud_ui_startup_notify(char const*)@Base" 3.8 + (c++)"aud_visualizer_remove(Visualizer*)@Base" 3.8 + (c++)"inifile_write_heading(VFSFile&, char const*)@Base" 3.8 + (c++)"str_has_prefix_nocase(char const*, char const*)@Base" 3.8 + (c++)"str_has_suffix_nocase(char const*, char const*)@Base" 3.8 + (c++)"aud_drct_enable_record(bool)@Base" 3.8 + (c++)"aud_drct_get_ab_repeat(int&, int&)@Base" 3.8 + (c++)"aud_drct_pl_next_album()@Base" 4.0 + (c++)"aud_drct_pl_prev_album()@Base" 4.0 + (c++)"aud_drct_set_ab_repeat(int, int)@Base" 3.8 + (c++)"aud_plugin_get_current(PluginType)@Base" 3.8 + (c++)"aud_plugin_get_enabled(PluginHandle*)@Base" 3.8 + (c++)"aud_plugin_menu_remove(AudMenuID, void (*)())@Base" 3.8 + (c++)"aud_config_set_defaults(char const*, char const* const*)@Base" 3.8 + (c++)"aud_plugin_get_basename(PluginHandle*)@Base" 3.8 + (c++)"aud_plugin_remove_watch(PluginHandle*, bool (*)(PluginHandle*, void*), void*)@Base" 3.8 + (c++)"aud_plugin_send_message(PluginHandle*, char const*, void const*, int)@Base" 3.8 + (c++)"aud_ui_hide_filebrowser()@Base" 3.8 + (c++)"aud_ui_show_filebrowser(bool)@Base" 3.8 + (c++)"aud_drct_get_volume_main()@Base" 3.8 + (c++)"aud_drct_set_volume_main(int)@Base" 3.8 + (c++)"aud_export_winamp_preset(EqualizerPreset const&, VFSFile&)@Base" 3.8 + (c++)"aud_file_can_write_tuple(char const*, PluginHandle*)@Base" 3.8 + (c++)"aud_plugin_get_qt_widget(PluginHandle*)@Base" 3.8 + (c++)"aud_plugin_has_configure(PluginHandle*)@Base" 3.8 + (c++)"aud_ui_hide_about_window()@Base" 3.8 + (c++)"aud_ui_hide_jump_to_song()@Base" 3.8 + (c++)"aud_ui_hide_prefs_window()@Base" 3.8 + (c++)"aud_ui_show_about_window()@Base" 3.8 + (c++)"aud_ui_show_jump_to_song()@Base" 3.8 + (c++)"aud_ui_show_prefs_window()@Base" 3.8 + (c++)"aud_import_winamp_presets(VFSFile&)@Base" 3.8 + (c++)"aud_plugin_get_gtk_widget(PluginHandle*)@Base" 3.8 + (c++)"aud_drct_get_record_plugin()@Base" 3.8 + (c++)"aud_drct_pl_open_temp_list(Index&&)@Base" 3.8 + (c++)"aud_plugin_lookup_basename(char const*)@Base" 3.8 + (c++)"aud_drct_get_record_enabled()@Base" 3.8 + (c++)"aud_drct_get_volume_balance()@Base" 3.8 + (c++)"aud_drct_set_volume_balance(int)@Base" 3.8 + (c++)"vfs_async_file_get_contents(char const*, void (*)(char const*, Index const&, void*), void*)@Base" 3.8 + (c++)"vfs_async_file_get_contents(char const*, std::function const&)>)@Base" 4.0 + (c++)"aud_plugin_get_supported_mime_types()@Base" 4.0 + (c++)"aud_run()@Base" 3.8 + (c++)"aud_init()@Base" 3.8 + (c++)"aud_quit()@Base" 3.8 + (c++)"str_copy(char const*, int)@Base" 3.8 + (c++)"hook_call(char const*, void*)@Base" 3.8 + (c++)"timer_add(TimerRate, void (*)(void*), void*)@Base" 3.8 + (c++)"tiny_lock(char*)@Base" 3.8 + (c++)"uri_parse(char const*, char const**, char const**, char const**, int*)@Base" 3.8 + (c++)"QueuedFunc::inhibit_all()@Base" 4.0 + (c++)"QueuedFunc::stop()@Base" 3.8 + (c++)"QueuedFunc::queue(void (*)(void*), void*)@Base" 3.8 + (c++)"QueuedFunc::queue(int, void (*)(void*), void*)@Base" 3.8 + (c++)"QueuedFunc::start(int, void (*)(void*), void*)@Base" 3.8 + (c++)"Visualizer::render_freq(float const*)@Base" 3.8 + (c++)"Visualizer::render_mono_pcm(float const*)@Base" 3.8 + (c++)"Visualizer::render_multi_pcm(float const*, int)@Base" 3.8 + (c++)"Visualizer::compute_freq_band(float const*, float const*, int, int)@Base" 4.0 + (c++)"Visualizer::compute_log_xscale(float*, int)@Base" 4.0 + (c++)"IfacePlugin::startup_notify(char const*)@Base" 3.8 + (c++)"InputPlugin::check_seek()@Base" 3.8 + (c++)"InputPlugin::check_stop()@Base" 3.8 + (c++)"InputPlugin::open_audio(int, int, int)@Base" 3.8 + (c++)"InputPlugin::write_audio(void const*, int)@Base" 3.8 + (c++)"InputPlugin::write_tuple(char const*, VFSFile&, Tuple const&)@Base" 3.8 + (c++)"InputPlugin::file_info_box(char const*, VFSFile&)@Base" 3.8 + (c++)"InputPlugin::set_replay_gain(ReplayGainInfo const&)@Base" 3.8 + (c++)"InputPlugin::get_playback_tuple()@Base" 3.8 + (c++)"InputPlugin::set_playback_tuple(Tuple&&)@Base" 3.8 + (c++)"InputPlugin::set_stream_bitrate(int)@Base" 3.8 + (c++)"RingBufBase::add(int)@Base" 3.8 + (c++)"RingBufBase::alloc(int)@Base" 3.8 + (c++)"RingBufBase::remove(int)@Base" 3.8 + (c++)"RingBufBase::copy_in(void const*, int, void (*)(void const*, void*, int))@Base" 3.8 + (c++)"RingBufBase::destroy(void (*)(void*, int))@Base" 3.8 + (c++)"RingBufBase::discard(int, void (*)(void*, int))@Base" 3.8 + (c++)"RingBufBase::move_in(void*, int, void (*)(void*, int))@Base" 3.8 + (c++)"RingBufBase::move_in(IndexBase&, int, int)@Base" 3.8 + (c++)"RingBufBase::move_out(void*, int, void (*)(void*, int))@Base" 3.8 + (c++)"RingBufBase::move_out(IndexBase&, int, int)@Base" 3.8 + (c++)"EffectPlugin::adjust_delay(int)@Base" 3.8 + (c++)"EffectPlugin::flush(bool)@Base" 3.8 + (c++)"EffectPlugin::finish(Index&, bool)@Base" 3.8 + (c++)"OutputPlugin::set_info(char const*, Tuple const&)@Base" 3.8 + (c++)"DockablePlugin::get_qt_widget()@Base" 3.8 + (c++)"DockablePlugin::get_gtk_widget()@Base" 3.8 + (c++)"PlaylistPlugin::save(char const*, VFSFile&, char const*, Index const&)@Base" 3.8 + (c++)"TransportPlugin::read_folder(char const*, String&)@Base" 3.8 + (c++)"TransportPlugin::test_file(char const*, VFSFileTest, String&)@Base" 3.8 + (c++)"Tuple::set_format(char const*, int, int, int)@Base" 3.8 + (c++)"Tuple::set_filename(char const*)@Base" 3.8 + (c++)"Tuple::set_subtunes(short, short const*)@Base" 3.8 + (c++)"Tuple::field_by_name(char const*)@Base" 3.8 + (c++)"Tuple::field_get_name(Tuple::Field)@Base" 3.8 + (c++)"Tuple::field_get_type(Tuple::Field)@Base" 3.8 + (c++)"Tuple::generate_title()@Base" 3.8 + (c++)"Tuple::delete_fallbacks()@Base" 3.8 + (c++)"Tuple::fetch_stream_info(VFSFile&)@Base" 3.8 + (c++)"Tuple::generate_fallbacks()@Base" 3.8 + (c++)"Tuple::unset(Tuple::Field)@Base" 3.8 + (c++)"Tuple::set_int(Tuple::Field, int)@Base" 3.8 + (c++)"Tuple::set_str(Tuple::Field, char const*)@Base" 3.8 + (c++)"Tuple::set_gain(Tuple::Field, Tuple::Field, char const*)@Base" 3.8 + (c++)"Tuple::set_state(Tuple::State)@Base" 3.8 + (c++)"Tuple::~Tuple()@Base" 3.8 + (c++)"Tuple::~Tuple()@Base" 3.8 + (c++)"Plugin::take_message(char const*, void const*, int)@Base" 3.8 + (c++)"Plugin::init()@Base" 3.8 + (c++)"Plugin::cleanup()@Base" 3.8 + (c++)"String::raw_get(char const*)@Base" 3.8 + (c++)"String::raw_ref(char const*)@Base" 3.8 + (c++)"String::raw_hash(char const*)@Base" 3.8 + (c++)"String::raw_equal(char const*, char const*)@Base" 3.8 + (c++)"String::raw_unref(char*)@Base" 3.8 + (c++)"audlog::unsubscribe(void (*)(audlog::Level, char const*, int, char const*, char const*))@Base" 3.8 + (c++)"audlog::get_level_name(audlog::Level)@Base" 3.8 + (c++)"audlog::set_stderr_level(audlog::Level)@Base" 3.8 + (c++)"audlog::log(audlog::Level, char const*, int, char const*, char const*, ...)@Base" 3.8 + (c++)"audlog::subscribe(void (*)(audlog::Level, char const*, int, char const*, char const*), audlog::Level)@Base" 3.8 + (c++|regex)"^VFSFile::write_file\(char const\*, void const\*, (long|long long)\)@Base$" 4.0 + (c++)"VFSFile::read_folder(char const*, String&)@Base" 3.8 + (c++)"VFSFile::get_metadata(char const*)@Base" 3.8 + (c++)"VFSFile::replace_with(VFSFile&)@Base" 3.8 + (c++)"VFSFile::set_limit_to_buffer(bool)@Base" 3.8 + (c++)"VFSFile::supported_uri_schemes()@Base" 4.0 + (c++)"VFSFile::feof()@Base" 3.8 + (c++|regex)"^VFSFile::fread\(void\*, (long|long long), (long|long long)\)@Base$" 3.8 + (c++|regex)"^VFSFile::fseek\((long|long long), VFSSeekType\)@Base$" 3.8 + (c++)"VFSFile::fsize()@Base" 3.8 + (c++)"VFSFile::ftell()@Base" 3.8 + (c++)"VFSFile::fflush()@Base" 3.8 + (c++|regex)"^VFSFile::fwrite\(void const\*, (long|long long), (long|long long)\)@Base$" 3.8 + (c++)"VFSFile::tmpfile()@Base" 3.8 + (c++)"VFSFile::read_all()@Base" 3.8 + (c++|regex)"^VFSFile::copy_from\(VFSFile&, (long|long long)\)@Base$" 3.8 + (c++|regex)"^VFSFile::ftruncate\((long|long long)\)@Base$" 3.8 + (c++)"VFSFile::read_file(char const*, VFSReadOptions)@Base" 4.0 + (c++)"VFSFile::test_file(char const*, VFSFileTest)@Base" 3.8 + (c++)"VFSFile::test_file(char const*, VFSFileTest, String&)@Base" 3.8 + (c++)"VFSFile::VFSFile(char const*, char const*)@Base" 3.8 + (c++)"VFSFile::VFSFile(char const*, char const*)@Base" 3.8 + (c++)"VFSImpl::get_metadata(char const*)@Base" 3.8 + (c++)"HashBase::add(HashBase::Node*, unsigned int)@Base" 3.8 + (c++)"HashBase::remove(HashBase::NodeLoc const&)@Base" 3.8 + (c++)"HashBase::iterate(bool (*)(HashBase::Node*, void*), void*)@Base" 3.8 + (c++)"ListBase::insert_after(ListNode*, ListNode*)@Base" 3.8 + (c++)"ListBase::clear(void (*)(ListNode*))@Base" 3.8 + (c++)"ListBase::remove(ListNode*)@Base" 3.8 + (c++)"Playlist::n_playlists()@Base" 3.9 + (c++)"Playlist::rescan_file(char const*)@Base" 3.9 + (c++)"Playlist::new_playlist()@Base" 3.9 + (c++)"Playlist::save_formats()@Base" 3.9 + (c++)"Playlist::blank_playlist()@Base" 3.9 + (c++)"Playlist::active_playlist()@Base" 3.9 + (c++)"Playlist::insert_playlist(int)@Base" 3.9 + (c++)"Playlist::playing_playlist()@Base" 3.9 + (c++)"Playlist::reorder_playlists(int, int, int)@Base" 3.9 + (c++)"Playlist::temporary_playlist()@Base" 3.9 + (c++)"Playlist::update_pending_any()@Base" 3.9 + (c++)"Playlist::add_in_progress_any()@Base" 3.9 + (c++)"Playlist::filename_is_playlist(char const*)@Base" 3.9 + (c++)"Playlist::scan_in_progress_any()@Base" 3.9 + (c++)"Playlist::process_pending_update()@Base" 4.0 + (c++)"Playlist::by_index(int)@Base" 3.9 + (c++)"IndexBase::sort(int (*)(void const*, void const*, void*), int, void*)@Base" 3.8 + (c++)"IndexBase::clear(void (*)(void*, int))@Base" 3.8 + (c++)"IndexBase::erase(int, int, void (*)(void*, int), void (*)(void*, int))@Base" 3.8 + (c++)"IndexBase::shift(int, int, int, void (*)(void*, int), void (*)(void*, int))@Base" 3.8 + (c++)"IndexBase::insert(void const*, int, int, void (*)(void const*, void*, int))@Base" 3.8 + (c++)"IndexBase::insert(int, int)@Base" 3.8 + (c++)"IndexBase::insert(int, int, void (*)(void*, int))@Base" 3.8 + (c++)"IndexBase::remove(int, int, void (*)(void*, int))@Base" 3.8 + (c++)"IndexBase::move_from(IndexBase&, int, int, int, bool, bool, void (*)(void*, int), void (*)(void*, int))@Base" 3.8 + (c++)"IniParser::parse(VFSFile&)@Base" 3.8 + (c++)"MultiHash::lookup(void const*, unsigned int, HashBase::Node* (*)(void const*, void*), bool (*)(HashBase::Node*, void*), void*)@Base" 3.8 + (c++)"MultiHash::iterate(bool (*)(HashBase::Node*, void*), void*)@Base" 3.8 + (c++)"MultiHash::iterate(bool (*)(HashBase::Node*, void*), void*, void (*)(void*), void*)@Base" 4.0 + (c++)"StringBuf::steal(StringBuf&&)@Base" 3.8 + (c++)"StringBuf::insert(int, char const*, int)@Base" 3.8 + (c++)"StringBuf::remove(int, int)@Base" 3.8 + (c++)"StringBuf::resize(int)@Base" 3.8 + (c++)"StringBuf::settle()@Base" 4.0 + (c++)"StringBuf::combine(StringBuf&&)@Base" 3.8 + (c++)"StringBuf::~StringBuf()@Base" 3.8 + (c++)"StringBuf::~StringBuf()@Base" 3.8 + (c++)"PlaylistEx::stamp() const@Base" 3.9 + (c++)"WidgetConfig::get_string() const@Base" 3.8 + (c++)"WidgetConfig::set_string(char const*) const@Base" 3.8 + (c++)"WidgetConfig::get_int() const@Base" 3.8 + (c++)"WidgetConfig::set_int(int) const@Base" 3.8 + (c++)"WidgetConfig::get_bool() const@Base" 3.8 + (c++)"WidgetConfig::set_bool(bool) const@Base" 3.8 + (c++)"WidgetConfig::get_float() const@Base" 3.8 + (c++)"WidgetConfig::set_float(double) const@Base" 3.8 + (c++)"Tuple::get_n_subtunes() const@Base" 3.8 + (c++)"Tuple::get_value_type(Tuple::Field) const@Base" 3.8 + (c++)"Tuple::get_nth_subtune(short) const@Base" 3.8 + (c++)"Tuple::get_replay_gain() const@Base" 3.8 + (c++)"Tuple::has_replay_gain() const@Base" 4.0 + (c++)"Tuple::ref() const@Base" 3.8 + (c++)"Tuple::state() const@Base" 3.8 + (c++)"Tuple::get_int(Tuple::Field) const@Base" 3.8 + (c++)"Tuple::get_str(Tuple::Field) const@Base" 3.8 + (c++)"Tuple::operator==(Tuple const&) const@Base" 3.8 + (c++)"HashBase::lookup(bool (*)(HashBase::Node const*, void const*), void const*, unsigned int, HashBase::NodeLoc*) const@Base" 3.8 + (c++)"Playlist::n_selected(int, int) const@Base" 3.9 + (c++)"Playlist::next_album(bool) const@Base" 4.0 + (c++)"Playlist::prev_album() const@Base" 4.0 + (c++)"Playlist::rescan_all() const@Base" 3.9 + (c++)"Playlist::select_all(bool) const@Base" 3.9 + (c++)"Playlist::entry_tuple(int, Playlist::GetMode, String*) const@Base" 3.9 + (c++)"Playlist::get_filename() const@Base" 3.9 + (c++)"Playlist::get_position() const@Base" 3.9 + (c++)"Playlist::insert_entry(int, char const*, Tuple&&, bool) const@Base" 3.9 + (c++)"Playlist::insert_items(int, Index&&, bool) const@Base" 3.9 + (c++)"Playlist::queue_insert(int, int) const@Base" 3.9 + (c++)"Playlist::queue_remove(int, int) const@Base" 3.9 + (c++)"Playlist::save_to_file(char const*, Playlist::GetMode) const@Base" 3.9 + (c++)"Playlist::select_entry(int, bool) const@Base" 3.9 + (c++)"Playlist::set_filename(char const*) const@Base" 3.9 + (c++)"Playlist::set_position(int) const@Base" 3.9 + (c++)"Playlist::sort_entries(Playlist::SortType) const@Base" 3.9 + (c++)"Playlist::entry_decoder(int, Playlist::GetMode, String*) const@Base" 3.9 + (c++)"Playlist::reverse_order() const@Base" 3.9 + (c++)"Playlist::shift_entries(int, int) const@Base" 3.9 + (c++)"Playlist::sort_by_tuple(int (*)(Tuple const&, Tuple const&)) const@Base" 3.9 + (c++)"Playlist::sort_selected(Playlist::SortType) const@Base" 3.9 + (c++)"Playlist::update_detail() const@Base" 3.9 + (c++)"Playlist::cache_selected() const@Base" 3.9 + (c++)"Playlist::entry_filename(int) const@Base" 3.9 + (c++)"Playlist::entry_selected(int) const@Base" 3.9 + (c++)"Playlist::remove_entries(int, int) const@Base" 3.9 + (c++)"Playlist::start_playback(bool) const@Base" 3.9 + (c++)"Playlist::update_pending() const@Base" 3.9 + (c++)"Playlist::add_in_progress() const@Base" 3.9 + (c++)"Playlist::insert_filtered(int, Index&&, bool (*)(char const*, void*), void*, bool) const@Base" 3.9 + (c++)"Playlist::queue_get_entry(int) const@Base" 3.9 + (c++)"Playlist::randomize_order() const@Base" 3.9 + (c++)"Playlist::remove_playlist() const@Base" 3.9 + (c++)"Playlist::remove_selected() const@Base" 3.9 + (c++)"Playlist::rescan_selected() const@Base" 3.9 + (c++)"Playlist::total_length_ms() const@Base" 3.9 + (c++)"Playlist::queue_find_entry(int) const@Base" 3.9 + (c++)"Playlist::reverse_selected() const@Base" 3.9 + (c++)"Playlist::scan_in_progress() const@Base" 3.9 + (c++)"Playlist::sort_by_filename(int (*)(char const*, char const*)) const@Base" 3.9 + (c++)"Playlist::remove_duplicates(Playlist::SortType) const@Base" 3.9 + (c++)"Playlist::randomize_selected() const@Base" 3.9 + (c++)"Playlist::remove_unavailable() const@Base" 3.9 + (c++)"Playlist::select_by_patterns(Tuple const&) const@Base" 3.9 + (c++)"Playlist::selected_length_ms() const@Base" 3.9 + (c++)"Playlist::queue_insert_selected(int) const@Base" 3.9 + (c++)"Playlist::queue_remove_selected() const@Base" 3.9 + (c++)"Playlist::sort_selected_by_tuple(int (*)(Tuple const&, Tuple const&)) const@Base" 3.9 + (c++)"Playlist::sort_selected_by_filename(int (*)(char const*, char const*)) const@Base" 3.9 + (c++)"Playlist::index() const@Base" 3.9 + (c++)"Playlist::activate() const@Base" 3.9 + (c++)"Playlist::n_queued() const@Base" 3.9 + (c++)"Playlist::get_focus() const@Base" 3.9 + (c++)"Playlist::get_title() const@Base" 3.9 + (c++)"Playlist::n_entries() const@Base" 3.9 + (c++)"Playlist::next_song(bool) const@Base" 3.9 + (c++)"Playlist::prev_song() const@Base" 3.9 + (c++)"Playlist::set_focus(int) const@Base" 3.9 + (c++)"Playlist::set_title(char const*) const@Base" 3.9 + (c++)"IndexBase::bsearch(void const*, int (*)(void const*, void const*, void*), int, void*) const@Base" 3.8 + (c++)"std::thread::_State_impl > >::_M_run()@Base" 4.0 + (c++)"std::thread::_State_impl > >::~_State_impl()@Base" 4.0 + (c++)"std::thread::_State_impl > >::~_State_impl()@Base" 4.0 + (c++)"std::thread::_State_impl > >::~_State_impl()@Base" 4.0 + (c++)"std::thread::_State_impl > >::_M_run()@Base" 4.0 + (c++)"std::thread::_State_impl > >::~_State_impl()@Base" 4.0 + (c++)"std::thread::_State_impl > >::~_State_impl()@Base" 4.0 + (c++)"std::thread::_State_impl > >::~_State_impl()@Base" 4.0 + (c++)"std::thread::~thread()@Base" 4.0 + (c++)"std::thread::~thread()@Base" 4.0 + (c++)"typeinfo for TransportPlugin@Base" 3.8 + (c++)"typeinfo for Plugin@Base" 3.8 + (c++)"typeinfo for VFSImpl@Base" 3.8 + (c++)"typeinfo for IniParser@Base" 3.8 + (c++)"typeinfo for std::thread::_State_impl > >@Base" 4.0 + (c++)"typeinfo for std::thread::_State_impl > >@Base" 4.0 + (c++)"typeinfo name for TransportPlugin@Base" 3.8 + (c++)"typeinfo name for Plugin@Base" 3.8 + (c++)"typeinfo name for VFSImpl@Base" 3.8 + (c++)"typeinfo name for IniParser@Base" 3.8 + (c++)"typeinfo name for std::thread::_State_impl > >@Base" 4.0 + (c++)"typeinfo name for std::thread::_State_impl > >@Base" 4.0 + (c++)"vtable for std::thread::_State_impl > >@Base" 4.0 + (c++)"vtable for std::thread::_State_impl > >@Base" 4.0 diff --git a/libaudgui5.install b/libaudgui5.install new file mode 100644 index 0000000..8fc2f3e --- /dev/null +++ b/libaudgui5.install @@ -0,0 +1 @@ +usr/lib/*/libaudgui.so.* diff --git a/libaudgui5.symbols b/libaudgui5.symbols new file mode 100644 index 0000000..d1c8497 --- /dev/null +++ b/libaudgui5.symbols @@ -0,0 +1,78 @@ +libaudgui.so.5 libaudgui5 #MINVER# + (c++)"audgui_init()@Base" 3.8 + (c++)"audgui_cleanup()@Base" 3.8 + (c++)"audgui_get_dpi()@Base" 3.8 + (c++)"audgui_button_new(char const*, char const*, void (*)(void*), void*)@Base" 3.8 + (c++)"audgui_dialog_new(GtkMessageType, char const*, char const*, _GtkWidget*, _GtkWidget*)@Base" 3.8 + (c++)"audgui_infowin_hide()@Base" 3.8 + (c++)"audgui_infowin_show(Playlist, int)@Base" 3.9 + (c++)"audgui_jump_to_time()@Base" 3.8 + (c++)"audgui_urilist_open(char const*)@Base" 3.8 + (c++)"audgui_jump_to_track()@Base" 3.8 + (c++)"audgui_list_get_user(_GtkWidget*)@Base" 3.8 + (c++)"audgui_list_new_real(AudguiListCallbacks const*, int, void*, int)@Base" 3.8 + (c++)"audgui_to_native_dpi(int)@Base" 3.8 + (c++)"audgui_vis_bar_color(_GdkColor const&, int, int, float&, float&, float&)@Base" 4.0 + (c++)"audgui_file_entry_new(GtkFileChooserAction, char const*)@Base" 3.8 + (c++)"audgui_infopopup_hide()@Base" 3.8 + (c++)"audgui_infopopup_show(Playlist, int)@Base" 3.9 + (c++)"audgui_list_get_focus(_GtkWidget*)@Base" 3.8 + (c++)"audgui_list_row_count(_GtkWidget*)@Base" 3.8 + (c++)"audgui_list_set_focus(_GtkWidget*, int)@Base" 3.8 + (c++)"audgui_pixbuf_request(char const*, bool*)@Base" 3.8 + (c++)"audgui_simple_message(_GtkWidget**, GtkMessageType, char const*, char const*)@Base" 3.8 + (c++)"audgui_urilist_insert(Playlist, int, char const*)@Base" 3.9 + (c++)"audgui_export_playlist()@Base" 3.8 + (c++)"audgui_get_digit_width(_GtkWidget*)@Base" 3.8 + (c++)"audgui_get_plugin_menu(AudMenuID)@Base" 3.8 + (c++)"audgui_import_playlist()@Base" 3.8 + (c++)"audgui_list_add_column(_GtkWidget*, char const*, int, unsigned long, int, bool)@Base" 3.9 + (c++)"audgui_pixbuf_fallback()@Base" 3.8 + (c++)"audgui_plugin_menu_add(AudMenuID, void (*)(), char const*, char const*)@Base" 3.8 + (c++)"audgui_run_filebrowser(bool)@Base" 3.8 + (c++)"audgui_to_portable_dpi(int)@Base" 3.8 + (c++)"audgui_dark_bg_gradient(_GdkColor const&, int)@Base" 4.0 + (c++)"audgui_get_mouse_coords(_GdkScreen*, int*, int*)@Base" 3.8 + (c++)"audgui_get_mouse_coords(_GtkWidget*, int*, int*)@Base" 3.8 + (c++)"audgui_hide_filebrowser()@Base" 3.8 + (c++)"audgui_list_delete_rows(_GtkWidget*, int, int)@Base" 3.8 + (c++)"audgui_list_insert_rows(_GtkWidget*, int, int)@Base" 3.8 + (c++)"audgui_list_update_rows(_GtkWidget*, int, int)@Base" 3.8 + (c++|regex)"^audgui_pixbuf_from_data\(void const\*, (long|long long)\)@Base$" 3.8 + (c++)"audgui_scaled_image_new(_GdkPixbuf*)@Base" 3.8 + (c++)"audgui_scaled_image_set(_GtkWidget*, _GdkPixbuf*)@Base" 3.8 + (c++)"audgui_destroy_on_escape(_GtkWidget*)@Base" 3.8 + (c++)"audgui_dialog_add_widget(_GtkWidget*, _GtkWidget*)@Base" 3.8 + (c++)"audgui_hide_about_window()@Base" 3.8 + (c++)"audgui_hide_prefs_window()@Base" 3.8 + (c++)"audgui_import_eq_presets(Index const&)@Base" 3.8 + (c++)"audgui_list_row_at_point(_GtkWidget*, int, int)@Base" 3.8 + (c++)"audgui_show_about_window()@Base" 3.8 + (c++)"audgui_show_plugin_about(PluginHandle*)@Base" 3.8 + (c++)"audgui_show_plugin_prefs(PluginHandle*)@Base" 3.8 + (c++)"audgui_show_prefs_window()@Base" 3.8 + (c++)"audgui_file_entry_get_uri(_GtkWidget*)@Base" 3.8 + (c++)"audgui_file_entry_set_uri(_GtkWidget*, char const*)@Base" 3.8 + (c++)"audgui_jump_to_track_hide()@Base" 3.8 + (c++)"audgui_list_get_highlight(_GtkWidget*)@Base" 3.8 + (c++)"audgui_list_set_highlight(_GtkWidget*, int)@Base" 3.8 + (c++)"audgui_plugin_menu_remove(AudMenuID, void (*)())@Base" 3.8 + (c++)"audgui_queue_manager_show()@Base" 3.8 + (c++)"audgui_pixbuf_scale_within(AudguiPixbuf&, int)@Base" 3.9 + (c++)"audgui_show_add_url_window(bool)@Base" 3.8 + (c++)"audgui_get_monitor_geometry(_GdkScreen*, int, int, _GdkRectangle*)@Base" 3.8 + (c++)"audgui_infowin_show_current()@Base" 3.8 + (c++)"audgui_show_playlist_rename(Playlist)@Base" 3.9 + (c++)"audgui_hide_equalizer_window()@Base" 3.8 + (c++)"audgui_list_update_selection(_GtkWidget*, int, int)@Base" 3.8 + (c++)"audgui_menu_init_with_domain(_GtkWidget*, ArrayRef, _GtkAccelGroup*, char const*)@Base" 3.8 + (c++)"audgui_show_eq_preset_window()@Base" 3.8 + (c++)"audgui_show_equalizer_window()@Base" 3.8 + (c++)"audgui_infopopup_show_current()@Base" 3.8 + (c++)"audgui_pixbuf_request_current(bool*)@Base" 3.8 + (c++)"audgui_confirm_playlist_delete(Playlist)@Base" 3.9 + (c++)"audgui_list_row_at_point_rounded(_GtkWidget*, int, int)@Base" 3.8 + (c++)"audgui_menu_item_new_with_domain(AudguiMenuItem const*, _GtkAccelGroup*, char const*)@Base" 3.8 + (c++)"audgui_show_prefs_for_plugin_type(PluginType)@Base" 3.8 + (c++)"audgui_urilist_create_from_selected(Playlist)@Base" 3.9 + images_get_resource@Base 4.0.5 diff --git a/libaudqt2.install b/libaudqt2.install new file mode 100644 index 0000000..746293a --- /dev/null +++ b/libaudqt2.install @@ -0,0 +1 @@ +usr/lib/*/libaudqt.so.* diff --git a/libaudqt2.symbols b/libaudqt2.symbols new file mode 100644 index 0000000..92188bc --- /dev/null +++ b/libaudqt2.symbols @@ -0,0 +1,111 @@ +libaudqt.so.2 libaudqt2 #MINVER# + (c++)"audqt::aboutwindow_hide()@Base" 3.7.1 + (c++)"audqt::aboutwindow_show()@Base" 3.7.1 + (c++)"audqt::art_request(char const*, bool*)@Base" 4.0 + (c++)"audqt::art_request(char const*, unsigned int, unsigned int, bool)@Base" 3.7.1 + (c++)"audqt::art_request_current(unsigned int, unsigned int, bool)@Base" 3.7.1 + (c++)"audqt::art_scale(QImage const&, unsigned int, unsigned int, bool)@Base" 4.0 + (c++)"audqt::cleanup()@Base" 3.7.1 + (c++)"audqt::clear_layout(QLayout*)@Base" 3.7.1 + (c++)"audqt::ColorButton::~ColorButton()@Base" 4.0 + (c++)"audqt::ColorButton::~ColorButton()@Base" 4.0 + (c++)"audqt::ColorButton::~ColorButton()@Base" 4.0 + (c++)"audqt::ColorButton::ColorButton(QWidget*)@Base" 4.0 + (c++)"audqt::ColorButton::ColorButton(QWidget*)@Base" 4.0 + (c++)"audqt::ColorButton::onColorChanged()@Base" 4.0 + (c++)"audqt::ColorButton::paintEvent(QPaintEvent*)@Base" 4.0 + (c++)"audqt::ColorButton::setColor(QColor const&)@Base" 4.0 + (c++)"audqt::dark_bg_gradient(QColor const&)@Base" 4.0 + (c++)"audqt::enable_layout(QLayout*, bool)@Base" 3.7.1 + (c++)"audqt::eq_presets_hide()@Base" 4.0 + (c++)"audqt::eq_presets_show()@Base" 4.0 + (c++)"audqt::equalizer_hide()@Base" 3.7.1 + (c++)"audqt::equalizer_show()@Base" 3.7.1 + (c++)"audqt::file_entry_get_uri(QLineEdit*)@Base" 4.0 + (c++)"audqt::file_entry_new(QWidget*, char const*, QFileDialog::FileMode, QFileDialog::AcceptMode)@Base" 4.0 + (c++)"audqt::file_entry_set_uri(QLineEdit*, char const*)@Base" 4.0 + (c++)"audqt::fileopener_show(audqt::FileMode)@Base" 3.7.1 + (c++)"audqt::font_entry_new(QWidget*, char const*)@Base" 4.0 + (c++)"audqt::get_icon(char const*)@Base" 4.0 + (c++)"audqt::infopopup_hide()@Base" 4.0 + (c++)"audqt::infopopup_show_current()@Base" 4.0 + (c++)"audqt::infopopup_show(Playlist, int)@Base" 4.0 + (c++)"audqt::InfoWidget::fillInfo(char const*, Tuple const&, PluginHandle*, bool)@Base" 4.0 + (c++)"audqt::InfoWidget::fillInfo(Index&&, bool)@Base" 4.0 + (c++)"audqt::InfoWidget::~InfoWidget()@Base" 3.7.1 + (c++)"audqt::InfoWidget::~InfoWidget()@Base" 3.7.1 + (c++)"audqt::InfoWidget::~InfoWidget()@Base" 3.7.1 + (c++)"audqt::InfoWidget::InfoWidget(QWidget*)@Base" 3.7.1 + (c++)"audqt::InfoWidget::InfoWidget(QWidget*)@Base" 3.7.1 + (c++)"audqt::InfoWidget::keyPressEvent(QKeyEvent*)@Base" 4.0 + (c++)"audqt::InfoWidget::linkEnabled(QWidget*)@Base" 4.0 + (c++)"audqt::InfoWidget::revertInfo()@Base" 4.0 + (c++)"audqt::InfoWidget::updateFile()@Base" 3.7.1 + (c++)"audqt::infowin_hide()@Base" 3.7.1 + (c++)"audqt::infowin_show_current()@Base" 3.7.1 + (c++)"audqt::infowin_show(Playlist, int)@Base" 4.0 + (c++)"audqt::infowin_show_selected(Playlist)@Base" 4.0 + (c++)"audqt::init()@Base" 3.7.1 + (c++)"audqt::log_inspector_hide()@Base" 3.7.1 + (c++)"audqt::log_inspector_show()@Base" 3.7.1 + (c++)"audqt::make_hbox(QWidget*, int)@Base" 4.0 + (c++)"audqt::make_vbox(QWidget*, int)@Base" 4.0 + (c++)"audqt::margins@Base" 4.0 + (c++)"audqt::menu_action(audqt::MenuItem const&, char const*, QWidget*)@Base" 3.7.1 + (c++)"audqt::menu_add(AudMenuID, void (*)(), char const*, char const*)@Base" 3.7.1 + (c++)"audqt::menubar_build(ArrayRef, char const*, QWidget*)@Base" 3.7.1 + (c++)"audqt::menu_build(ArrayRef, char const*, QWidget*)@Base" 3.7.1 + (c++)"audqt::menu_get_by_id(AudMenuID)@Base" 3.7.1 + (c++)"audqt::menu_remove(AudMenuID, void (*)())@Base" 3.7.1 + (c++)"audqt::playlist_confirm_delete(Playlist)@Base" 4.0 + (c++)"audqt::playlist_show_rename(Playlist)@Base" 4.0 + (c++)"audqt::plugin_about(PluginHandle*)@Base" 3.7.1 + (c++)"audqt::plugin_prefs(PluginHandle*)@Base" 3.7.1 + (c++)"audqt::prefswin_hide()@Base" 3.7.1 + (c++)"audqt::prefswin_show()@Base" 3.7.1 + (c++)"audqt::prefswin_show_page(int, bool)@Base" 3.7.1 + (c++)"audqt::prefswin_show_plugin_page(PluginType)@Base" 3.7.1 + (c++)"audqt::qfont_from_string(char const*)@Base" 4.0 + (c++)"audqt::qfont_to_string(QFont const&)@Base" 4.0 + (c++)"audqt::queue_manager_hide()@Base" 3.7.1 + (c++)"audqt::queue_manager_show()@Base" 3.7.1 + (c++)"audqt::quit()@Base" 3.7.1 + (c++)"audqt::run()@Base" 3.7.1 + (c++)"audqt::simple_message(char const*, char const*)@Base" 3.7.1 + (c++)"audqt::simple_message(char const*, char const*, QMessageBox::Icon)@Base" 3.7.1 + (c++)"audqt::sizes@Base" 4.0 + (c++)"audqt::translate_str(char const*, char const*)@Base" 3.7.1 + (c++)"audqt::TreeView::activate(QModelIndex const&)@Base" 4.0 + (c++)"audqt::TreeView::keyPressEvent(QKeyEvent*)@Base" 4.0 + (c++)"audqt::TreeView::mouseDoubleClickEvent(QMouseEvent*)@Base" 4.0 + (c++)"audqt::TreeView::removeSelectedRows()@Base" 4.0 + (c++)"audqt::TreeView::~TreeView()@Base" 4.0 + (c++)"audqt::TreeView::~TreeView()@Base" 4.0 + (c++)"audqt::TreeView::~TreeView()@Base" 4.0 + (c++)"audqt::TreeView::TreeView(QWidget*)@Base" 4.0 + (c++)"audqt::TreeView::TreeView(QWidget*)@Base" 4.0 + (c++)"audqt::urlopener_show(bool)@Base" 3.7.1 + (c++)"audqt::vis_bar_color(QColor const&, int, int)@Base" 4.0 + (c++)"audqt::volume_button_new(QWidget*)@Base" 4.0 + (c++)"audqt::window_bring_to_front(QWidget*)@Base" 3.7.1 + (c++)"non-virtual thunk to audqt::ColorButton::~ColorButton()@Base" 4.0 + (c++)"non-virtual thunk to audqt::ColorButton::~ColorButton()@Base" 4.0 + (c++)"non-virtual thunk to audqt::InfoWidget::~InfoWidget()@Base" 3.7.1 + (c++)"non-virtual thunk to audqt::InfoWidget::~InfoWidget()@Base" 3.7.1 + (c++)"non-virtual thunk to audqt::InfoWidget::~InfoWidget()@Base" 3.7.1 + (c++)"non-virtual thunk to audqt::InfoWidget::~InfoWidget()@Base" 3.7.1 + (c++)"non-virtual thunk to audqt::TreeView::~TreeView()@Base" 4.0 + (c++)"non-virtual thunk to audqt::TreeView::~TreeView()@Base" 4.0 + (c++)"QByteArray::~QByteArray()@Base" 3.7.1 + (c++)"QByteArray::~QByteArray()@Base" 3.7.1 + (c++)"QString::~QString()@Base" 3.7.1 + (c++)"QString::~QString()@Base" 3.7.1 + (c++)"typeinfo for audqt::ColorButton@Base" 4.0 + (c++)"typeinfo for audqt::InfoWidget@Base" 4.0 + (c++)"typeinfo for audqt::TreeView@Base" 4.0 + (c++)"typeinfo name for audqt::ColorButton@Base" 4.0 + (c++)"typeinfo name for audqt::InfoWidget@Base" 4.0 + (c++)"typeinfo name for audqt::TreeView@Base" 4.0 + (c++)"vtable for audqt::ColorButton@Base" 4.0 + (c++)"vtable for audqt::InfoWidget@Base" 4.0 + (c++)"vtable for audqt::TreeView@Base" 4.0 diff --git a/libaudtag3.install b/libaudtag3.install new file mode 100644 index 0000000..1f148ee --- /dev/null +++ b/libaudtag3.install @@ -0,0 +1 @@ +usr/lib/*/libaudtag.so.* diff --git a/libaudtag3.symbols b/libaudtag3.symbols new file mode 100644 index 0000000..c252db9 --- /dev/null +++ b/libaudtag3.symbols @@ -0,0 +1,4 @@ +# SymbolsHelper-Confirmed: 3.9 amd64 +libaudtag.so.3 libaudtag3 #MINVER# + (c++)"audtag::write_tuple(VFSFile&, Tuple const&, audtag::TagType)@Base" 3.8 + (c++)"audtag::read_tag(VFSFile&, Tuple&, Index*)@Base" 3.8 diff --git a/patches/add-keywords.patch b/patches/add-keywords.patch new file mode 100644 index 0000000..e0a726a --- /dev/null +++ b/patches/add-keywords.patch @@ -0,0 +1,15 @@ +Description: Add keywords to desktop file +Author: Mateusz Łukasik + +--- a/audacious.desktop ++++ b/audacious.desktop +@@ -5,7 +5,8 @@ + GenericName=Music Player + Comment=Listen to music + Icon=audacious +-Categories=AudioVideo;Audio;Player; ++Keywords=audio;player;audacious;music;gtk; ++Categories=AudioVideo;Audio;Player;GTK; + Exec=audacious %U + TryExec=audacious + StartupNotify=false diff --git a/patches/default-to-gtk.patch b/patches/default-to-gtk.patch new file mode 100644 index 0000000..c18504b --- /dev/null +++ b/patches/default-to-gtk.patch @@ -0,0 +1,39 @@ +From: Andrej Shadura +Subject: Default to the GTK interface, not Qt + +--- a/src/audacious/main.cc ++++ b/src/audacious/main.cc +@@ -50,6 +50,7 @@ + int mainwin, show_jump_box; + int headless, quit_after_play; + int verbose; ++ int qt; + int gtk; + } options; + +@@ -78,6 +79,7 @@ + {"quit-after-play", 'q', & options.quit_after_play, N_("Quit on playback stop")}, + {"verbose", 'V', & options.verbose, N_("Print debugging messages (may be used twice)")}, + #if defined(USE_QT) && defined(USE_GTK) ++ {"qt", 'Q', & options.qt, N_("Run in Qt mode")}, + {"gtk", 'G', & options.gtk, N_("Run in GTK mode")}, + #endif + }; +@@ -171,8 +173,16 @@ + else if (options.verbose) + audlog::set_stderr_level (audlog::Info); + +- if (options.gtk) ++ if (options.qt && options.gtk) { ++ fprintf (stderr, _("Conflicting options: --gtk and --qt\n")); ++ return false; ++ } ++ ++ if (options.qt) { ++ aud_set_mainloop_type (MainloopType::Qt); ++ } else { + aud_set_mainloop_type (MainloopType::GLib); ++ } + + return true; + } diff --git a/patches/qt-option-man.patch b/patches/qt-option-man.patch new file mode 100644 index 0000000..d15cf78 --- /dev/null +++ b/patches/qt-option-man.patch @@ -0,0 +1,25 @@ +From: Jonathan Rubenstein +Date: Sun, 26 Apr 2020 14:28:27 -0400 +Subject: Describe Qt and GTK options in audacious manpage + +--- + man/audacious.1.in | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/man/audacious.1.in b/man/audacious.1.in +index aceaa51..cefa1ac 100644 +--- a/man/audacious.1.in ++++ b/man/audacious.1.in +@@ -77,6 +77,12 @@ Print debugging output while running (may be used twice for even more output). + .B -N, --new-instance + Starts a new instance. The second instance started may be controlled with + \fBaudtool -2\fR, the third with \fBaudtool -3\fR, etc. (up to 9 instances). ++.TP ++.B -G, --gtk ++Start Audacious using the GTK+ interface. ++.TP ++.B -Q, --qt ++Start Audacious using the Qt interface. + + .SH KEYBINDINGS + .ta 24 diff --git a/patches/series b/patches/series new file mode 100644 index 0000000..2164759 --- /dev/null +++ b/patches/series @@ -0,0 +1,3 @@ +add-keywords.patch +default-to-gtk.patch +qt-option-man.patch diff --git a/rules b/rules new file mode 100755 index 0000000..6243986 --- /dev/null +++ b/rules @@ -0,0 +1,36 @@ +#!/usr/bin/make -f + +DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) +DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) + +ifeq ($(DEB_BUILD_ARCH),i386) +additional_confflags := --disable-sse2 +endif + +# Do not link against unused libraries (make dpkg-shlibdeps happy). +LDFLAGS += -Wl,-z,defs -Wl,--as-needed +export DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow + +%: + dh $@ + +override_dh_auto_configure: + dh_auto_configure -- --disable-rpath --enable-chardet $(additional_confflags) \ + --with-buildstamp="$(shell dpkg-vendor --query vendor) package" --enable-gtk + +override_dh_auto_install: + dh_auto_install + # Move the arch-specific headers into the multiarch domain + cd debian/tmp/usr/include && \ + mkdir -p $(DEB_HOST_MULTIARCH)/libaudcore && \ + mv libaudcore/audio.h $(DEB_HOST_MULTIARCH)/libaudcore/ + +override_dh_installdirs: + dh_installdirs + mkdir -p debian/tmp/usr/share/pixmaps + convert images/audacious.png -resize 16x16 debian/tmp/usr/share/pixmaps/audacious-16.xpm + convert images/audacious.png -resize 32x32 debian/tmp/usr/share/pixmaps/audacious-32.xpm + +override_dh_auto_clean: + dh_auto_clean || true + rm -f src/libaudcore/audio.h diff --git a/source/format b/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/source/lintian-overrides b/source/lintian-overrides new file mode 100644 index 0000000..a705454 --- /dev/null +++ b/source/lintian-overrides @@ -0,0 +1,5 @@ +# this is not relevant to us +source: wayward-symbolic-link-target-in-source contrib/macpack/Audacious.app/Contents/MacOS/audacious + +# the upstream always releases plugins and the core in sync +source: version-substvar-for-external-package audacious -> audacious-plugins diff --git a/upstream/metadata b/upstream/metadata new file mode 100644 index 0000000..87763fe --- /dev/null +++ b/upstream/metadata @@ -0,0 +1,2 @@ +Repository: https://github.com/audacious-media-player/audacious.git +Repository-Browse: https://github.com/audacious-media-player/audacious diff --git a/watch b/watch new file mode 100644 index 0000000..a3ddaea --- /dev/null +++ b/watch @@ -0,0 +1,2 @@ +version=4 +https://distfiles.audacious-media-player.org/audacious-([^-]*)\.tar\.bz2 -- cgit v1.2.3 From cadf5659e38dff8cf024810eeb66a2e82a994f5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ukasik?= Date: Wed, 13 Oct 2021 21:45:42 +0200 Subject: Add keywords to desktop file Gbp-Pq: Name add-keywords.patch --- audacious.desktop | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/audacious.desktop b/audacious.desktop index 804b27c..a0827e6 100644 --- a/audacious.desktop +++ b/audacious.desktop @@ -5,7 +5,8 @@ Name=Audacious GenericName=Music Player Comment=Listen to music Icon=audacious -Categories=AudioVideo;Audio;Player; +Keywords=audio;player;audacious;music;gtk; +Categories=AudioVideo;Audio;Player;GTK; Exec=audacious %U TryExec=audacious StartupNotify=false -- cgit v1.2.3 From 5a6615f98c8c80fe33158bf7ca7853a36c8b1102 Mon Sep 17 00:00:00 2001 From: Andrej Shadura Date: Wed, 13 Oct 2021 21:45:42 +0200 Subject: Default to the GTK interface, not Qt Gbp-Pq: Name default-to-gtk.patch --- src/audacious/main.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/audacious/main.cc b/src/audacious/main.cc index 1213a95..3c56676 100644 --- a/src/audacious/main.cc +++ b/src/audacious/main.cc @@ -50,6 +50,7 @@ static struct { int mainwin, show_jump_box; int headless, quit_after_play; int verbose; + int qt; int gtk; } options; @@ -78,6 +79,7 @@ static const struct { {"quit-after-play", 'q', & options.quit_after_play, N_("Quit on playback stop")}, {"verbose", 'V', & options.verbose, N_("Print debugging messages (may be used twice)")}, #if defined(USE_QT) && defined(USE_GTK) + {"qt", 'Q', & options.qt, N_("Run in Qt mode")}, {"gtk", 'G', & options.gtk, N_("Run in GTK mode")}, #endif }; @@ -171,8 +173,16 @@ static bool parse_options (int argc, char * * argv) else if (options.verbose) audlog::set_stderr_level (audlog::Info); - if (options.gtk) + if (options.qt && options.gtk) { + fprintf (stderr, _("Conflicting options: --gtk and --qt\n")); + return false; + } + + if (options.qt) { + aud_set_mainloop_type (MainloopType::Qt); + } else { aud_set_mainloop_type (MainloopType::GLib); + } return true; } -- cgit v1.2.3 From fb912a62525a22e1fb24afd38b6384f827704a55 Mon Sep 17 00:00:00 2001 From: Jonathan Rubenstein Date: Sun, 26 Apr 2020 14:28:27 -0400 Subject: Describe Qt and GTK options in audacious manpage Gbp-Pq: Name qt-option-man.patch --- man/audacious.1.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/man/audacious.1.in b/man/audacious.1.in index aceaa51..cefa1ac 100644 --- a/man/audacious.1.in +++ b/man/audacious.1.in @@ -77,6 +77,12 @@ Print debugging output while running (may be used twice for even more output). .B -N, --new-instance Starts a new instance. The second instance started may be controlled with \fBaudtool -2\fR, the third with \fBaudtool -3\fR, etc. (up to 9 instances). +.TP +.B -G, --gtk +Start Audacious using the GTK+ interface. +.TP +.B -Q, --qt +Start Audacious using the Qt interface. .SH KEYBINDINGS .ta 24 -- cgit v1.2.3